Estoy trabajando con un FragmentStatePagerAdapter utilizando este ejemplo.

La MyAdapter clase se implementa de la siguiente manera:

public static class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            return ArrayListFragment.newInstance(position);
        }
    }

La ListFragment clase incluye el método siguiente para crear una nueva instancia:

    /**
     * Create a new instance of CountingFragment, providing "num"
     * as an argument.
     */
    static ArrayListFragment newInstance(int num) {
        ArrayListFragment f = new ArrayListFragment();

        //Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }

Cuando creo un nuevo fragmento estado adaptador buscapersonas en mi actividad, getItem se llama, que a su vez llama a la newInstance método en el ListFragment clase. Esto es genial cuando quiero crear un nuevo fragmento.

Pero no me queda claro cómo modificar getItem (si es necesario) para obtener el fragmento de objeto cuando ya existe y las páginas de usuario, por ejemplo, en la página 2 de la página 1. Me gustaría que mi Actividad para recuperar existente, previamente creado fragmento de modo que puede ejecutar una clase interna AsyncMethod, que reside en el fragmento de la clase.

getItem() tiene un nombre raro, no proporciona la funcionalidad que usted está pensando. Por favor revise mi propia pregunta sobre el mismo tema: stackoverflow.com/questions/10574114/…
Esto parece muy útil. Pero estoy usando un ListFragment y tenía la esperanza de utilizar getSelectedItemPosition en lugar de hacer mi propio getPosition. Necesito jugar con él un poco más y ver si puedo averiguar cómo hacerlo.
He utilizado ListFragment demasiado, pero simplemente no funciona de esta manera. Sin embargo, si encuentras algo, me encantaría saber
En lugar de newInstance (), ¿por qué no crear un getInstance() método en su ArrayListFragment – que devuelve una estática singleton?
yo estaba tratando de hacerlo con una sola llamada a estático getInstance() en mi fragmento. cant adjuntar el mismo fragmento de nuevo a pesar de

OriginalEl autor mraviator | 2012-05-18

5 Comentarios

  1. 3

    Me han implementado algo similar a lo que tengo. Me extendió la FragmentPagerAdapter clase así:

    public class ContactsFragmentPagerAdapter extends FragmentPagerAdapter {
        ActionBar mActionBar;
        private List<Fragment> mFragments;
    
        public ContactsFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            mFragments = fragments;
        }
    
        @Override
        public int getCount() {
            return mFragments.size();
        }
    
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
    
        public void setActionBar(ActionBar bar) {
            mActionBar = bar;
        }
    }

    Aviso he añadido un argumento para el constructor a pasar en el List de Fragment objetos. De esta manera el getItem() método de esta clase puede devolver cualquier clase que extiende Fragment o de cualquiera de sus subclases y no solo en una clase específica ArrayListFragment como usted lo ha hecho.

    En el Activity donde puedo crear instancias de mi subclase de FragmentPagerAdapter me han pasado en la lista de Fragment objetos:

    De la clase de la instancia a la FragmentPagerAdapter

    public final class ContactManager extends Activity {
        private ContactsFragmentPagerAdapter mAdapter;
        private ViewPager mPager;
        public ActionBar mActionBar;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.contact_manager);
    
            List<Fragment> fragments = new Vector<Fragment>();
            fragments.add(Fragment.instantiate(this, ContactsListFragment.class.getName()));
            fragments.add(Fragment.instantiate(this, GroupsListFragment.class.getName()));
            mAdapter = new ContactsFragmentPagerAdapter(this.getFragmentManager(), fragments);
    
            mPager = (ViewPager) findViewById(R.id.pager);
            mPager.setAdapter(mAdapter);
    
            mPager.setOnPageChangeListener(new OnPageChangeListener() {
                @Override
                public void onPageScrollStateChanged(int arg0) {}
    
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {}
    
                @Override
                public void onPageSelected(int arg0) {
                    mActionBar.getTabAt(arg0).select();
                }
            });
    
        }
    
    }

    Accediendo a la variable «fragmentos», se puede acceder a una creada previamente Fragment para que pueda ejecutar los métodos de que Fragment.

    Sería agradable si había una solución que no todos los fragmentos siempre crea una instancia para trabajar bien con FragmentStatePagerAdapter, ya que es realmente el punto de que el adaptador.

    OriginalEl autor toobsco42

  2. 40

    Creo que la solución es mucho más simple que las respuestas que se dieron.

    Si usted echa un vistazo a la fuente de FragmentStatePagerAdapter.instantiateItem(), te darás cuenta de que instantiateItem() maneja esta lógica para usted, y por lo tanto la implementación de getItem() siempre debe devolver una nueva instancia.

    Así que para volver a una ya existente Fragmento, simplemente hacer (suponiendo que usted está llamando desde ViewPager):

    Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem());
    La mejor respuesta que estaba escondido en la parte inferior !!! public void onPageScrolled(int i, float v, int i2) { Fragmento de fragmento = (Fragmento)imagePagerAdapter.instantiateItem(mImageViewPager,i);
    Sólo después de mirar el origen de ¿me doy cuenta de la lógica del problema. Y ver que esta es la única respuesta lógica en la página. Muchas gracias.
    Esta debe ser la respuesta seleccionada (junto con @RyanHeitner comentario en donde el uso de este método). Gracias.

    OriginalEl autor imiric

  3. 8

    Mientras que @imiric la solución es muy conciso, todavía me molesta que se requiere el conocimiento de la implementación de la clase. Mi solución consiste en añadir el siguiente a su adaptador, que deben comportarse bien con un FragmentStatePagerAdapter posiblemente la destrucción de los fragmentos:

        private SparseArray<WeakReference<Fragment>> mFragments = new SparseArray<>();
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment f = (Fragment) super.instantiateItem(container, position);
            mFragments.put(position, new WeakReference<>(f));  //Remember what fragment was in position
            return f;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            super.destroyItem(container, position, object);
            mFragments.remove(position);
        }
    
        public Fragment getFragment(int position) {
            WeakReference<Fragment> ref = mFragments.get(position);
            Fragment f = ref != null ? ref.get() : null;
            if (f == null) {
                Log.d(TAG, "fragment for " + position + " is null!");
            }
            return f;
        }
    No se debe mantener las referencias a Fragmentos como se puede ser destruido y recreado en cualquier momento. Sus referencias no será válido si eso sucede y los Fragmentos no puede ser el recolector de basura.
    De hecho! No actualización que utilizar WeakReferences ser suficiente, aunque?
    Me lo creo

    OriginalEl autor qix

  4. 5
    public class MyPagerAdapter extends FragmentStatePagerAdapter {
        final Context m_context;
        final WeakReference<Fragment>[] m_fragments;
    
        public DetailPagerAdapter(FragmentManager fm) {
            super(fm);
            m_context = ...
                    m_fragments = new WeakReference[enter size here];
        }
    
        @Override
        public Fragment getItem(int position) {
            final Fragment fragment = instantiate your fragment;
            m_fragments[position] = new WeakReference<Fragment>(fragment);
            return fragment;
        }
    
        @Override
        public int getCount() {
            return ...
        }
    
        public Fragment getFragment(final int position) {
            return m_fragments[position] == null ? null :
                m_fragments[position].get();
        }
    }

    OriginalEl autor farid_z

  5. 0

    No necesita modificar el FragmentPagerAdapter, debido a que los fragmentos se almacenan en caché por el FragmentManager. Así que usted debe necesitar encontrar en su interior. Utilice esta función para encontrar el fragmento de pager posición del adaptador.

    public Fragment findFragmentByPosition(int position) {
        FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
        return getSupportFragmentManager().findFragmentByTag(
                "android:switcher:" + getViewPager().getId() + ":"
                        + fragmentPagerAdapter.getItemId(position));
    }

    Código de ejemplo para la v4 apoyo de la api.

    Es esta incluido en el código de ejemplo para el apoyo de la api o ¿se escribe a sí mismo para el apoyo de la api? (Si no, me sería de al menos «semi-oficial»)
    Escribo esto por mí mismo, basado en el código fuente de Android API, y he sentido por el «código de ejemplo para v4» es debido a que este código se utilice «getSupportFragmentManager», que está disponible cuando se utiliza la biblioteca de compatibilidad, En caso de no utilizar el apoyo de la biblioteca’, usted necesitará por lo menos un cambio «getSupportFragmentManager» para «getFragmentManager». FYI: developer.android.com/tools/extras/support-library.html
    Thx. Yo esperaba que lo había hecho oficial, de alguna manera. Esto podría romper en el futuro… Ah, bueno, pero gracias!
    No te preocupes por eso, porque Android está basado en Java philosophi. «Escribir una vez, ejecutar en cualquier lugar»… para siempre.

    OriginalEl autor Daniel De León

Dejar respuesta

Please enter your comment!
Please enter your name here