He creado una actividad que utiliza FragmentStatePagerAdapter para proporcionar pequeña galería. Sin embargo, no consigo que se actualice cuando se reanuda la actividad (después de volver de otra actividad, por ejemplo). Cada vez que dos primeras fotografías serán en blanco, y sólo después de pasar dos fotos al lado, que refrescarse. Ninguna de las respuestas que he encontrado trabajo (especialmente primordial getItemPosition())

Lo configuro como este:

mPagerAdapter = new PhotosPagerAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.photosViewPager);
mPager.setAdapter(mPagerAdapter);

Entonces he FragmentStatePagerAdapter clase:

private class PhotosPagerAdapter extends FragmentStatePagerAdapter{

    public PhotosPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return photos.size();   
    }

    @Override
    public Fragment getItem(int position) {
        ImageFragment f = new ImageFragment(position);
        return f;
    }

    @Override
    public int getItemPosition(Object object) {
        throw new RuntimeException();
        //return POSITION_NONE;
    }

}

Como usted probablemente ha notado, me tiro RuntimeException en getItemPosition, porque quería comprobar si es necesario. Y no se llama así hasta que agregar algo a la lista que contiene mis fotos. Luego ImageFragment clase:

public class ImageFragment extends Fragment{

    int position;
    Bitmap mBitmap;
    int width;
    int height;
    ImageView img;

    public ImageFragment(){
    }

    public ImageFragment(int position){
        this.position = position;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        img = new ImageView(container.getContext());
        img.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        width = container.getWidth();
        height = container.getHeight();

        loadBitmap();

        return img;
    }       

    public void loadBitmap(){
        if (img == null){
            return;
        }
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(photos.get(position), options);
        options.inSampleSize = calculateInSampleSize(options, width/2, height/2);
        options.inJustDecodeBounds = false;
        mBitmap = BitmapFactory
                .decodeFile(photos.get(position), options);         

        img.setImageBitmap(mBitmap);
    }


    @Override
    public void onDestroyView() {
        mBitmap.recycle();
        super.onDestroyView();
    }       
}

Código es un poco desordenada después traté de solucionarlo… Pero: la eliminación de onDestroyView() no funciona. He puesto mPagerAdapter.notifyDataSetChanged() en algunos de los lugares que debe ser llamado (como onResume()), sin resultado alguno. Me estoy poniendo un poco desesperado con eso.

OriginalEl autor wasyl | 2012-12-04

4 Comentarios

  1. 37

    Tratar con fragmento de buscapersonas adaptadores pueden ser un pan de PITA.

    Aquí hay algunos consejos útiles:

    ViewPager PagerAdapter no actualizar la Vista

    Actualización ViewPager dinámicamente?

    Generalmente éste funciona el 99% del tiempo…

    Reemplazar getItemPosition en su PagerAdapter como este:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    A veces, incluso los que no funcionan, tengo que usar la «fuerza bruta» y recrear toda la vista de nuevo (desde onCreate en adelante)…

    Obras correspondientes a la del adaptador notifyDataSetChanged() la llamada.

    OriginalEl autor logray

  2. 4

    Yo estaba teniendo un problema similar como tu, después de algunas investigaciones que he creado una bonita secuencia de comandos que evitar la creación de fragmentos que ya están allí, pero al mismo tiempo, permitir la actualización de todo lo visible/iniciado fragmento.

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.view.ViewGroup;
    import java.util.WeakHashMap;
    /**
    * Created by TheCobra on 9/17/15.
    */
    public abstract class FragmentAdvanceStatePagerAdapter extends FragmentStatePagerAdapter
    {
    private WeakHashMap<Integer, Fragment> mFragments;
    public FragmentAdvanceStatePagerAdapter(FragmentManager fm)
    {
    super(fm);
    mFragments = new WeakHashMap<Integer, Fragment>();
    }
    @Override
    public Fragment getItem(int position)
    {
    Fragment item = getFragmentItem(position);
    mFragments.put(Integer.valueOf(position), item);
    return item;
    }
    @Override
    public void destroyItem(ViewGroup container, int position, Object object)
    {
    super.destroyItem(container, position, object);
    Integer key = Integer.valueOf(position);
    if (mFragments.containsKey(key))
    {
    mFragments.remove(key);
    }
    }
    @Override
    public void notifyDataSetChanged()
    {
    super.notifyDataSetChanged();
    for (Integer position : mFragments.keySet())
    {
    //Make sure we only update fragments that should be seen
    if (position != null && mFragments.get(position) != null && position.intValue() < getCount())
    {
    updateFragmentItem(position, mFragments.get(position));
    }
    }
    }
    @Override
    public int getItemPosition(Object object)
    {
    //If the object is a fragment, check to see if we have it in the hashmap
    if (object instanceof Fragment)
    {
    int position = findFragmentPositionHashMap((Fragment) object);
    //If fragment found in the hashmap check if it should be shown
    if (position >= 0)
    {
    //Return POSITION_NONE if it shouldn't be display
    return (position >= getCount()? POSITION_NONE : position);
    }
    }
    return super.getItemPosition(object);
    }
    /**
    * Find the location of a fragment in the hashmap if it being view
    * @param object the Fragment we want to check for
    * @return the position if found else -1
    */
    protected int findFragmentPositionHashMap(Fragment object)
    {
    for (Integer position : mFragments.keySet())
    {
    if (position != null &&
    mFragments.get(position) != null &&
    mFragments.get(position) == object)
    {
    return position;
    }
    }
    return -1;
    }
    public abstract Fragment getFragmentItem(int position);
    public abstract void updateFragmentItem(int position, Fragment fragment);
    }

    Copiar ese código en un archivo de nombre «FragmentAdvanceStatePagerAdapter.java». Ahora en su adaptador, se extienden desde el este y reemplazar «getFragmentItem()» & «updateFragmentItem()». Cuando usted llame a notifydatachange(), updateFragmentItem() será llamado con todo el fragmento ya creado. Cuando el adaptador de la necesidad de crear un nuevo fragmento, getFragmentItem() será llamado.

    Espero que salvar y ayudar a mucha gente 🙂

    Buena Suerte y feliz de Programación!!!

    P. S. el adaptador «getItem()» debe ser «getFragmentItem()» si el uso de esta clase.

    He actualizado para corregir un bug que he encontrado en el código.

    OriginalEl autor TheCobra

  3. 1

    Nunca se acaba de uso POSITION_NONE uso

    if(fragmentManager.getFragments().contains(object))
    return POSITION_NONE;
    else
    return POSITION_UNCHANGED;

    para evitar el Fatal Exception: java.lang.IllegalStateException
    Fragmento {} no está actualmente en la FragmentManager

    No funciona para mí

    OriginalEl autor Tyler Davis

Dejar respuesta

Please enter your comment!
Please enter your name here