Tengo problemas con mi fragmentos de comunicarse unos con otros a través de la Activity, que está utilizando el FragmentPagerAdapter, como un ayudante de la clase que implementa la gestión de pestañas y todos los detalles de la conexión de un ViewPager con asociados TabHost. He implementado FragmentPagerAdapter sólo como la misma que es proporcionada por el Android de proyecto de ejemplo Support4Demos.

La pregunta principal es ¿cómo puedo obtener un fragmento concreto de FragmentManager cuando no tengo ni Id o Etiqueta? FragmentPagerAdapter es la creación de los fragmentos y el auto generar el Identificador y Etiquetas.

  • Posibles duplicados de Llegar a la actual Fragmento de instancia en el viewpager
  • ¿cómo puede ser esto un duplicado de una pregunta que se formuló después de 1 año de
  • duplicado como una etiqueta, no relacionados con el tiempo, más tarde las preguntas tienen más puntos de vista
InformationsquelleAutor Ismar Slomic | 2012-12-26

14 Comentarios

  1. 179

    Resumen del problema

    Nota: En esta respuesta voy a referencia FragmentPagerAdapter y de su código fuente. Pero la solución general debe aplicarse también a FragmentStatePagerAdapter.

    Si estás leyendo esto, probablemente ya sabes que FragmentPagerAdapter/FragmentStatePagerAdapter está destinado a crear Fragments para su ViewPager, pero en la Actividad de recreación (ya sea desde un dispositivo de rotación o el sistema de la matanza de su App para recuperar la memoria de estos Fragments no se crean de nuevo, pero en su lugar instancias recuperado de FragmentManager. Ahora dicen que su Activity necesita obtener una referencia a estos Fragments para hacer un trabajo sobre ellos. Usted no tiene un id o tag para la creación de estas Fragments porque FragmentPagerAdapter conjunto de ellos internamente. Así que el problema es cómo obtener una referencia a ellos sin que esa información…

    Problema con las soluciones actuales: confiando en código interno

    Muchas de las soluciones que he visto en esta y otras preguntas similares se basan en conseguir una referencia a la existente Fragment llamando FragmentManager.findFragmentByTag() y la imitación de la internamente creado etiqueta: «android:switcher:» + viewId + «:» + id. El problema con esto es que usted debe confiar en lo interno, código fuente, que como todos sabemos no es garantizado a seguir siendo los mismos de siempre. El Android de los ingenieros de Google se decida a cambiar el tag estructura que podría romper su código de dejar que se puede encontrar una referencia a la existente Fragments.

    Solución alternativa, sin depender de los internos tag

    He aquí un ejemplo simple de cómo obtener una referencia a la Fragments devuelto por FragmentPagerAdapter que no dependen de la interna tags establecido en el Fragments. La clave es reemplazar instantiateItem() y guardar las referencias allí lugar de getItem().

    public class SomeActivity extends Activity {
    private FragmentA m1stFragment;
    private FragmentB m2ndFragment;
    //other code in your Activity...
    private class CustomPagerAdapter extends FragmentPagerAdapter {
    //other code in your custom FragmentPagerAdapter...
    public CustomPagerAdapter(FragmentManager fm) {
    super(fm);
    }
    @Override
    public Fragment getItem(int position) {
    //Do NOT try to save references to the Fragments in getItem(),
    //because getItem() is not always called. If the Fragment
    //was already created then it will be retrieved from the FragmentManger
    //and not here (i.e. getItem() won't be called again).
    switch (position) {
    case 0:
    return new FragmentA();
    case 1:
    return new FragmentB();
    default:
    //This should never happen. Always account for each position above
    return null;
    }
    }
    //Here we can finally safely save a reference to the created
    //Fragment, no matter where it came from (either getItem() or
    //FragmentManger). Simply save the returned Fragment from
    //super.instantiateItem() into an appropriate reference depending
    //on the ViewPager position.
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
    //save the appropriate reference depending on position
    switch (position) {
    case 0:
    m1stFragment = (FragmentA) createdFragment;
    break;
    case 1:
    m2ndFragment = (FragmentB) createdFragment;
    break;
    }
    return createdFragment;
    }
    }
    public void someMethod() {
    //do work on the referenced Fragments, but first check if they
    //even exist yet, otherwise you'll get an NPE.
    if (m1stFragment != null) {
    //m1stFragment.doWork();
    }
    if (m2ndFragment != null) {
    //m2ndFragment.doSomeWorkToo();
    }
    }
    }

    o si usted prefiere trabajar con tags en lugar de las variables miembro de clase/referencias a la Fragments puede también tomar la tags establecido por FragmentPagerAdapter de la misma manera:
    NOTA: esto no se aplica a FragmentStatePagerAdapter ya que no establece tags a la hora de crear su Fragments.

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
    //get the tags set by FragmentPagerAdapter
    switch (position) {
    case 0:
    String firstTag = createdFragment.getTag();
    break;
    case 1:
    String secondTag = createdFragment.getTag();
    break;
    }
    //... save the tags somewhere so you can reference them later
    return createdFragment;
    }

    Tenga en cuenta que este método NO se basa en la imitación de los internos tag establecido por FragmentPagerAdapter y en su lugar utiliza el Api adecuadas para la recuperación de ellos. De esta manera, incluso si el tag cambios en futuras versiones de la SupportLibrary usted todavía será seguro.


    No olvides que dependiendo del diseño de su Activity, el Fragments usted está tratando de trabajar en la que puede o puede no existir todavía, así que se tiene en cuenta que al hacer null comprobaciones antes de usar sus referencias.

    También, si en lugar estás trabajando con FragmentStatePagerAdapter, entonces usted no desea mantener duro referencias a su Fragments porque puede tener muchos de ellos y duro referencias que innecesariamente mantenerlos en la memoria. En lugar de guardar el Fragment referencias en WeakReference variables en lugar de los estándar. Como este:

    WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment);
    //...and access them like so
    Fragment firstFragment = m1stFragment.get();
    if (firstFragment != null) {
    //reference hasn't been cleared yet; do work...
    }
    • Esta es una muy buena solución, pero parece perder su eficacia si usted no sabe cómo muchos de los fragmentos que se ha pasado.
    • puede almacenar el crear fragmentos en un HashMap: mapa.poner(posición, createdFragment);
    • Esto merece la marca! Muy inteligente y de manera integral para lograr esto. Me has ayudado mucho gracias!
    • Esto funciona muy bien con las etiquetas, pero no de la otra manera. También he tenido que comprobar el valor null de referencia en el instantiateitem método y volver de nuevo Fragmento() si nula es verdadera. Pero buen ejemplo. ayudó mucho
    • Al principio esta solución parecía demasiado complicado, así que lo omití. Finalmente llegué a ella, sin embargo, porque las otras respuestas no eran satisfactorias. Y no fue tan difícil como pensé.
    • no hay necesidad de reemplazar cualquier cosa y en realidad se no ser primordial instantiateItem. la manera correcta de hacer esto es para llamada instantiateItem en onCreate método de su actividad rodeada de startUpdate y finishUpdate. Ver mi respuesta para más detalles
    • Explicación muy completa. Gracias!
    • Chan Cómo utilizar viewPagerAdapter ? Si la actividad se vuelve a crear, tenemos que crear una nueva instancia de viewPagerAdapter y ViewPager, cómo este instantiateItem() va a ayudar ? Si el adaptador está recién creado, entonces todo es nuevo. Por favor ayuda con el código de respuesta ?
    • sí, saludos. fue llegar null referencias a mi fragmentos en el adaptador. se preguntaba qué estaba pasando. por desgracia, yo era omnly agregar a mi lista de referencias en getItem(). así que tengo referencias de edad. saludos!
    • Hizo que mi fin de semana, gracias! He utilizado el reemplazado crear instancias de método.
    • el mejor método que he visto hasta ahora. No se si Android decide no poner ETIQUETAS más en el futuro, este se rompería. Aunque supongo que esto no sucederá. El marco debe tener esta solución fuera de la caja, aunque
    • Cuando se utiliza FragmentStatePagerAdapter esta es una respuesta incompleta. Recomiendo mirar el código fuente de éste en android.googlesource.com/platform/frameworks/support/+/…

  2. 80

    He encontrado respuesta a mi pregunta se basa en el siguiente post: la reutilización de fragmentos en un fragmentpageradapter

    Par de cosas que he aprendido:

    1. getItem(int position) en el FragmentPagerAdapter es bastante engañoso nombre de lo que este método realmente. Crea nuevos fragmentos, no devolución de los ya existentes. En tan sentido, el método se debe cambiar el nombre a algo como createItem(int position) en el SDK de Android. Por lo que este método no nos ayuda a conseguir los fragmentos.
    2. Basada en la explicación en el post apoyo FragmentPagerAdapterholds referencia a fragmentos debe dejar la creación de los fragmentos de la FragmentPagerAdapter y en lo que significa que usted no tiene ninguna referencia a los Fragmentos o sus etiquetas. Si usted tiene fragmento de la etiqueta, sin embargo, usted puede fácilmente recuperar referencia a él desde la FragmentManager llamando findFragmentByTag(). Necesitamos una manera de averiguar la etiqueta de un fragmento en la página determinada posición.

    Solución

    Agregar el siguiente método en su clase para recuperar un fragmento de la etiqueta y enviarlo a la findFragmentByTag() método.

    private String getFragmentTag(int viewPagerId, int fragmentPosition)
    {
    return "android:switcher:" + viewPagerId + ":" + fragmentPosition;
    }

    NOTA! Esto es idéntico método que FragmentPagerAdapter utilizar en la creación de nuevos fragmentos. Ver en este enlace http://code.google.com/p/openintents/source/browse/trunk/compatibility/AndroidSupportV2/src/android/support/v2/app/FragmentPagerAdapter.java#104

    • Por cierto, hay más sobre el tema en este Q&A: stackoverflow.com/questions/6976027/…
    • ¿cuál es la viewId parámetro de entrada? Qué punto de vista?
    • viewId es el identificador de la ViewPager.
    • No funciona con FragmentStatePagerAdapter
    • Tal vez en lugar de adivinar la etiqueta el fragmento podría decirle a su etiqueta de su actividad en onAttach()?
    • Gracias por este funciona como un encanto
    • No es que no funciona con FragmentStatePagerAdapter
    • Este no es el camino correcto. @Tony Chan respuesta es la mejor y de la manera correcta.
    • A mí me funciona, estado luchando durante un día entero tratando de arreglar un error relacionado con esto. Gracias
    • no hay necesidad de volver a crear fragmento de etiquetas y dependen de la compatibilidad con el código interno: se puede (y de hecho se debe) de la llamada instantiateItem en onCreate método de su actividad rodeada de startUpdate y finishUpdate para obtener referencias a fragmentos (fragmentos se almacenan en caché en FragmentManager, así que no hay necesidad de preocuparse de que iba a crear instancias innecesarias). Ver mi respuesta para más detalles.
    • por Encima de las Soluciones es la forma correcta para resolver este problema. Nota tiene que establecer la setOffscreenPageLimit() si el uso de FragmentStatePagerAdapter. Manera más simple de usar findFragmentByTag() se puede encontrar en link

  3. 12

    no es necesario reemplazar instantiateItem ni depender de la compatibilidad de la creación de fragmento etiquetas internas makeFragmentName método. instantiateItem es un público método para que usted puede (y de hecho se debe) llamada en onCreate método de su actividad para obtener referencias a instancias de sus fragmentos y almacenarlos en vars locales si es necesario. Sólo recuerde que rodean a un conjunto de instantiateItem llamadas con
    startUpdate y finishUpdate métodos descritos en PagerAdapter javadoc:

    Una llamada a la PagerAdapter método startUpdate(ViewGroup) indica que el contenido de la ViewPager están a punto de cambiar. Una o más llamadas a instantiateItem(ViewGroup, int) y/o destroyItem(ViewGroup, int, Objeto de los que le siguen, y el final de una actualización será señalado por una llamada a finishUpdate(ViewGroup).

    Así, por ejemplo, esta es la forma de almacenar referencias a su ficha fragmentos en onCreate método:

    public class MyActivity extends AppCompatActivity {
    Fragment0 tab0; Fragment1 tab1;
    @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.myLayout);
    ViewPager viewPager = (ViewPager) findViewById(R.id.myViewPager);
    MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);
    ((TabLayout) findViewById(R.id.tabs)).setupWithViewPager(viewPager);
    adapter.startUpdate(viewPager);
    tab0 = (Fragment0) adapter.instantiateItem(viewPager, 0);
    tab1 = (Fragment1) adapter.instantiateItem(viewPager, 1);
    adapter.finishUpdate(viewPager);
    }
    class MyPagerAdapter extends FragmentPagerAdapter {
    public MyPagerAdapter(FragmentManager manager) {super(manager);}
    @Override public int getCount() {return 2;}
    @Override public Fragment getItem(int position) {
    if (position == 0) return new Fragment0();
    if (position == 1) return new Fragment1();
    return null;  //or throw some exception
    }
    @Override public CharSequence getPageTitle(int position) {
    if (position == 0) return getString(R.string.tab0);
    if (position == 1) return getString(R.string.tab1);
    return null;  //or throw some exception
    }
    }
    }

    instantiateItem primero intentará obtener referencias existentes fragmento instancias de FragmentManager. Sólo si no existe, sin embargo, va a crear nuevos con getItem método de su adaptador y «tienda» en la FragmentManager para cualquier uso futuro.

    Alguna información adicional:

    Si usted no llama a instantiateItem rodeado por startUpdate/finishUpdate en su onCreate método, a continuación, se arriesga a que su fragmento casos nunca será comprometido a FragmentManager: cuando su actividad se convierte en primer plano instantiateItem será llamado automáticamente para obtener sus fragmentos, pero startUpdate/finishUpdate puede no (dependiendo de los detalles de implementación) y lo que, básicamente, es begin/commit un FragmentTransaction.

    Este puede resultado en las referencias a la creación fragmento casos se pierde muy rápidamente (por ejemplo, al girar la pantalla) y recreado mucho más a menudo de lo necesario. Dependiendo de que tan «pesada» de sus fragmentos, puede tener un no despreciable consecuencias en el rendimiento.

    Lo que es más importante, sin embargo, en tales casos, las instancias de fragmentos almacenados en vars locales se conviertan en obsoletos: desde la plataforma android no fue capaz de obtener las mismas instancias de FragmentManager puede crear y utilizar nuevos, mientras que su vars todavía va a ser la referencia de los viejos.

    • Podría ser la mejor solución en algunos casos. Pero, ¿qué pasaría si FragmentManger va a matar el fragmento y recrate es?
    • no puede simplemente al azar matar (destruir es la palabra adecuada) de su Fragment (pensar qué pasaría si decidiera matar a un Fragment que se está mostrando actualmente 😉 ). En general el ciclo de vida de un Fragment está obligado a su Activity (ver github.com/xxv/android-lifecycle para obtener más detalles) -> un Fragment sólo pueden ser destruidas si su Activity fue destruido. En tal caso cuando un usuario navega de regreso a la Activity su onCreate será llamado de nuevo y una nueva instancia de la Fragment será creado.
    • Gran respuesta, muchas gracias!
    • Esta es la VERDADERA Respuesta
    • Debe usted realmente cree fragmentos en lugar de confiar en ellos, que se crea como un usuario se desplaza ViewPager, por ejemplo?
    • sí, usted realmente debe. El docs extracto que claramente los estados y «algo de información adicional» sección explica por qué.

  4. 11

    La manera en que lo hice es definir una tabla Hash de WeakReferences de la siguiente manera:

    protected Hashtable<Integer, WeakReference<Fragment>> fragmentReferences;

    Entonces escribí el getItem() método como este:

    @Override
    public Fragment getItem(int position) {
    Fragment fragment;
    switch(position) {
    case 0:
    fragment = new MyFirstFragmentClass();
    break;
    default:
    fragment = new MyOtherFragmentClass();
    break;
    }
    fragmentReferences.put(position, new WeakReference<Fragment>(fragment));
    return fragment;
    }

    Entonces usted puede escribir un método:

    public Fragment getFragment(int fragmentId) {
    WeakReference<Fragment> ref = fragmentReferences.get(fragmentId);
    return ref == null ? null : ref.get();
    }

    Esto parece funcionar bien y me parece que es un poco menos chapucero de la

    "android:switcher:" + viewId + ":" + position

    truco, ya que no se basa en cómo el FragmentPagerAdapter se implementa.
    Por supuesto, si el fragmento ha sido publicado por el FragmentPagerAdapter o si no ha sido creado todavía, getFragment devolverá null.

    Si alguien encuentra algo malo con este enfoque, los comentarios son más que bienvenidos.

    • int fragmentId se debe cambiar el nombre a int position
    • Yo estaba usando un enfoque similar. Pero esta falla cuando el localizador es creado a partir de un savedState paquete. por ejemplo: la Actividad continúa en el fondo y vuelve a primer plano después de la onSavedStateInstance() es llamado. En ese caso, el getItem() métodos no ser llamado.
    • Esto no funciona
    • ¿cuál es la razón para crear su propio mapa, ya que hay uno en FragmentManager ya que siempre es up2date? Ver mi respuesta para más detalles.
    • también, el hecho de que un fragmento ha sido destruido, no garantiza que no hay referencias fuertes a ella (aunque es probable, pero NO garantizado), en cuyo caso su mapa todavía contienen rancio fragmentos.
  5. 10

    He creado este método, que es trabajo para mí para obtener una referencia a la actual fragmento.

    public static Fragment getCurrentFragment(ViewPager pager, FragmentPagerAdapter adapter) {
    try {
    Method m = adapter.getClass().getSuperclass().getDeclaredMethod("makeFragmentName", int.class, long.class);
    Field f = adapter.getClass().getSuperclass().getDeclaredField("mFragmentManager");
    f.setAccessible(true);
    FragmentManager fm = (FragmentManager) f.get(adapter);
    m.setAccessible(true);
    String tag = null;
    tag = (String) m.invoke(null, pager.getId(), (long) pager.getCurrentItem());
    return fm.findFragmentByTag(tag);
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    } 
    return null;
    }
    • Bueno sólo para recordar la creación del Método de Campo y fuera de el método para mejorar el rendimiento
  6. 2

    la solución sugerida por @personne3000 es bonito, pero tiene un problema: cuando la actividad se va al fondo y se mató por el sistema (con el fin de obtener algo de memoria libre) y, a continuación, restaurar, el fragmentReferences estará vacía, porque getItem no ser llamado.

    La clase a continuación se encarga de la situación:

    public abstract class AbstractHolderFragmentPagerAdapter<F extends Fragment> extends FragmentPagerAdapter {
    public static final String FRAGMENT_SAVE_PREFIX = "holder";
    private final FragmentManager fragmentManager; //we need to store fragment manager ourselves, because parent's field is private and has no getters.
    public AbstractHolderFragmentPagerAdapter(FragmentManager fm) {
    super(fm);
    fragmentManager = fm;
    }
    private SparseArray<WeakReference<F>> holder = new SparseArray<WeakReference<F>>();
    protected void holdFragment(F fragment) {
    holdFragment(holder.size(), fragment);
    }
    protected void holdFragment(int position, F fragment) {
    if (fragment != null)
    holder.put(position, new WeakReference<F>(fragment));
    }
    public F getHoldedItem(int position) {
    WeakReference<F> ref = holder.get(position);
    return ref == null ? null : ref.get();
    }
    public int getHolderCount() {
    return holder.size();
    }
    @Override
    public void restoreState(Parcelable state, ClassLoader loader) { //code inspired by Google's FragmentStatePagerAdapter implementation
    super.restoreState(state, loader);
    Bundle bundle = (Bundle) state;
    for (String key : bundle.keySet()) {
    if (key.startsWith(FRAGMENT_SAVE_PREFIX)) {
    int index = Integer.parseInt(key.substring(FRAGMENT_SAVE_PREFIX.length()));
    Fragment f = fragmentManager.getFragment(bundle, key);
    holdFragment(index, (F) f);
    }
    }
    }
    @Override
    public Parcelable saveState() {
    Bundle state = (Bundle) super.saveState();
    if (state == null)
    state = new Bundle();
    for (int i = 0; i < holder.size(); i++) {
    int id = holder.keyAt(i);
    final F f = getHoldedItem(i);
    String key = FRAGMENT_SAVE_PREFIX + id;
    fragmentManager.putFragment(state, key, f);
    }
    return state;
    }
    }
  7. 2

    La carretera principal bloque con la obtención de un identificador de los fragmentos es que usted no puede confiar en getItem(). Después de un cambio de orientación, las referencias a los fragmentos serán nulos y getItem() no se llama de nuevo.

    Aquí un enfoque que no se basa en la aplicación de FragmentPagerAdapter para obtener la etiqueta. Reemplazar instantiateItem (), que devuelve el fragmento creado a partir de getItem() o que se encuentran desde el fragmento de administrador.

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    Object value =  super.instantiateItem(container, position);
    if (position == 0) {
    someFragment = (SomeFragment) value;
    } else if (position == 1) {
    anotherFragment = (AnotherFragment) value;
    }
    return value;
    }
  8. 2

    Yo siempre uso esta clase de base, cuando necesito acceder a niño fragmentos o primaria (actualmente visible) fragmento. No depende de los detalles de implementación y se encarga del ciclo de vida para los cambios, porque sobrescribir los métodos llamados en ambos casos – cuando un nuevo fragmento de la instancia creada y cuando la instancia se recibió de FragmentManager.

    public abstract class FragmentPagerAdapterExt extends FragmentPagerAdapter {
    private final ArrayList<Fragment> mFragments;
    private Fragment mPrimaryFragment;
    public FragmentPagerAdapterExt(FragmentManager fm) {
    super(fm);
    mFragments = new ArrayList<>(getCount());
    }
    @Override public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    mFragments.add((Fragment) object);
    return object;
    }
    @Override public void destroyItem(ViewGroup container, int position, Object object) {
    mFragments.remove(object);
    super.destroyItem(container, position, object);
    }
    @Override public void setPrimaryItem(ViewGroup container, int position, Object object) {
    super.setPrimaryItem(container, position, object);
    mPrimaryFragment = (Fragment) object;
    }
    /** Returns currently visible (primary) fragment */
    public Fragment getPrimaryFragment() {
    return mPrimaryFragment;
    }
    /** Returned list can contain null-values for not created fragments */
    public List<Fragment> getFragments() {
    return Collections.unmodifiableList(mFragments);
    }
    }
    • Este puede estar fallando cuando la actividad es asesinado de fondo y luego de reiniciar? getFragments() devuelve una lista con todos los valores nulos.
  9. 1

    Me las arreglé para resolver este problema mediante el uso de identificadores en lugar de las etiquetas. (Estoy usando he definido FragmentStatePagerAdapter que utiliza mi costumbre de los Fragmentos en los que me hicieron caso omiso de los onAttach método, donde se guarda el id en algún lugar:

    @Override
    public void onAttach(Context context){
    super.onAttach(context);
    MainActivity.fragId = getId();
    }

    Y, a continuación, usted acaba de acceder al fragmento con facilidad dentro de la actividad:

    Fragment f = getSupportFragmentManager.findFragmentById(fragId);
  10. 0

    Ver este post en la devolución de los fragmentos de la FragmentPagerAdapter. No dependen de usted conocer el índice de su fragmento -, pero esto sería establecer en getItem() (en la creación de instancias sólo)

  11. 0

    No sé si este es el mejor método, pero nada funcionó para mí.
    Todas las otras opciones, incluyendo getActiveFragment devuelve null o ha causado que la aplicación se bloquee.

    Me di cuenta de que en la rotación de la pantalla el fragmento que se va a adjuntar, por lo que he usado para enviar el fragmento de vuelta a la actividad.

    En el fragmento:

    @Override
    public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
    mListener = (OnListInteractionListener) activity;
    mListener.setListFrag(this);
    } catch (ClassCastException e) {
    throw new ClassCastException(activity.toString()
    + " must implement OnFragmentInteractionListener");
    }
    }

    A continuación, en la actividad:

    @Override
    public void setListFrag(MyListFragment lf) {
    if (mListFragment == null) {
    mListFragment = lf;
    }
    }

    Y, finalmente, en la actividad onCreate():

    if (savedInstanceState != null) {
    if (mListFragment != null)
    mListFragment.setListItems(items);
    }

    Este enfoque concede la real visible un fragmento de la actividad sin crear uno nuevo.

  12. 0

    No estoy seguro si mi método era la correcta o la mejor manera de hacer esto ya que tengo un pariente principiante con Java/Android, pero se hizo el trabajo (estoy seguro de que viola el objeto de principios orientados, pero no hay otra solución trabajado para mi caso de uso).

    Tuve un hosting Actividad que estaba usando un ViewPager con un FragmentStatePagerAdapter. Con el fin de obtener referencias a los Fragmentos que fueron creados por FragmentStatePagerAdapter he creado una interfaz de devolución de llamada en el fragmento de la clase:

    public interface Callbacks {
    public void addFragment (Fragment fragment);
    public void removeFragment (Fragment fragment);
    }

    En el hosting de la actividad que he implementado la interfaz y creó un LinkedHasSet de seguir la pista de los fragmentos:

    public class HostingActivity extends AppCompatActivity implements ViewPagerFragment.Callbacks {
    private LinkedHashSet<Fragment> mFragments = new LinkedHashSet<>();
    @Override
    public void addFragment (Fragment fragment) {
    mFragments.add(fragment);
    }
    @Override
    public void removeFragment (Fragment fragment) {
    mFragments.remove(fragment);
    }
    }

    Dentro de la ViewPagerFragment clase he añadido los fragmentos de la lista dentro de onAttach y les quitan dentro de onDetach:

    public class ViewPagerFragment extends Fragment {
    private Callbacks mCallbacks;
    public interface Callbacks {
    public void addFragment (Fragment fragment);
    public void removeFragment (Fragment fragment);
    } 
    @Override
    public void onAttach (Context context) {
    super.onAttach(context);
    mCallbacks = (Callbacks) context;
    //Add this fragment to the HashSet in the hosting activity
    mCallbacks.addFragment(this);
    }
    @Override
    public void onDetach() {
    super.onDetach();
    //Remove this fragment from the HashSet in the hosting activity
    mCallbacks.removeFragment(this);
    mCallbacks = null;
    }
    }

    Dentro del alojamiento de la actividad de ahora vamos a ser capaces de utilizar mFragments para iterar a través de los fragmentos que existen actualmente en el FragmentStatePagerAdapter.

  13. 0

    Esta clase de hacer el truco sin depender de variables internas. Advertencia: los Fragmentos deben ser accedidos usando el getFragment método y no el getItem uno.

    public class ViewPagerAdapter extends FragmentPagerAdapter {
    private final Map<Integer, Reference<Fragment>> fragments = new HashMap<>();
    private final List<Callable0<Fragment>> initializers = new ArrayList<>();
    private final List<String> titles = new ArrayList<>();
    public ViewPagerAdapter(FragmentManager fm) {
    super(fm);
    }
    void addFragment(Callable0<Fragment> initializer, String title) {
    initializers.add(initializer);
    titles.add(title);
    }
    public Optional<Fragment> getFragment(int position) {
    return Optional.ofNullable(fragments.get(position).get());
    }
    @Override
    public Fragment getItem(int position) {
    Fragment fragment =  initializers.get(position).execute();
    return fragment;
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    fragments.put(position, new WeakReference<>(fragment));
    return fragment;
    }
    @Override
    public int getCount() {
    return initializers.size();
    }
    @Override
    public CharSequence getPageTitle(int position) {
    return titles.get(position);
    }
    }
  14. -5

    Sólo tienes que ir a probar este código,

    public class MYFragmentPAdp extends FragmentPagerAdapter {
    public MYFragmentPAdp(FragmentManager fm) {
    super(fm);
    }
    @Override
    public int getCount() {
    return 2;
    }
    @Override
    public Fragment getItem(int position) {
    if (position == 0)
    Fragment fragment = new Fragment1();
    else (position == 1)
    Fragment fragment = new Fragment2();
    return fragment;
    }
    }
    • Najib, como expliqué en mi respuesta por debajo de getItem()es la creación de nuevas fragmento en lugar de la devolución de los ya existentes como uno podría esperar dado el nombre de get y no crear. Ver mi solución en el mismo post.
    • Fragmento de fragmento = new YourCustomFragmentClass(); escribir aquí verificar esto.
    • Yo todavía no entiendo cómo esto cambia el hecho de que usted está creando nuevo fragmento en lugar de llegar existente..
    • Todavía inicializar y volver personalizado fragmento sólo,como el Fragmento de fragmento = new YourFragment(); return fragmento;

Dejar respuesta

Please enter your comment!
Please enter your name here