obtener el último fragmento en backstack

¿Cómo puedo obtener la última instancia de fragmento añadida en backstack (si no conozco la etiqueta de fragmento y el ID)?

FragmentManager fragManager = activity.getSupportFragmentManager(); FragmentTransaction fragTransacion = fragMgr.beginTransaction(); /****After add , replace fragments (some of the fragments are add to backstack , some are not)***/ //HERE, How can I get the latest added fragment from backstack ?? 

Puede usar el método getName() de FragmentManager.BackStackEntry que se introdujo en el nivel 14 de API. Este método devolverá una etiqueta que fue la que utilizó cuando agregó el Fragment a la backstack con addTobackStack(tag) .

 int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1 FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index); String tag = backEntry.getName(); Fragment fragment = getFragmentManager().findFragmentByTag(tag); 

Debes asegurarte de haber agregado el fragmento a la backstack de esta manera:

 fragmentTransaction.addToBackStack(tag); 
 FragmentManager.findFragmentById(fragmentsContainerId) 

la función devuelve el enlace al principio Fragment en backstack. Ejemplo de uso:

  fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() { @Override public void onBackStackChanged() { Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer); if(fr!=null){ Log.e("fragment=", fr.getClass().getSimpleName()); } } }); 

Personalmente probé muchas de esas soluciones y terminé con esta solución de trabajo:

Agregue este método de utilidad que se usará varias veces a continuación para obtener la cantidad de fragmentos en su backstack:

 protected int getFragmentCount() { return getSupportFragmentManager().getBackStackEntryCount(); } 

Luego, cuando agrega / reemplaza su fragmento usando el método FragmentTransaction, genere una etiqueta única para su fragmento (por ejemplo: usando la cantidad de fragmentos en su stack):

 getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount())); 

Finalmente, puedes encontrar cualquiera de tus fragmentos en tu backstack con este método:

 private Fragment getFragmentAt(int index) { return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null; } 

Por lo tanto, puede obtener fácilmente el fragmento superior en su backstack llamando a:

 protected Fragment getCurrentFragment() { return getFragmentAt(getFragmentCount() - 1); } 

¡Espero que esto ayude!

Hay una lista de fragmentos en fragmentMananger. Tenga en cuenta que eliminar un fragmento no hace que el tamaño de la lista disminuya (la entrada del fragmento acaba convirtiéndose en nulo). Por lo tanto, una solución válida sería:

 public Fragment getTopFragment() { List fragentList = fragmentManager.getFragments(); Fragment top = null; for (int i = fragentList.size() -1; i>=0 ; i--) { top = (Fragment) fragentList.get(i); if (top != null) { return top; } } return top; } 

La respuesta dada por deepak goel no me funciona porque siempre obtengo nulo de entry.getName() ;

Lo que hago es establecer una etiqueta para el fragmento de esta manera:

 ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG); 

Donde ft es mi fragmento de transacción y FRAGMENT_TAG es la etiqueta. Luego uso este código para obtener el fragmento:

 Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG); 

este método de ayuda obtiene un fragmento de la parte superior de la stack:

 public Fragment getTopFragment() { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { return null; } String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); return getSupportFragmentManager().findFragmentByTag(fragmentTag); } 

Mantenga su propia stack de respaldo: myBackStack . A medida que Add un fragmento al FragmentManager , también agréguelo a myBackStack . En onBackStackChanged() myBackStack de myBackStack cuando su longitud es mayor que getBackStackEntryCount .

puedes usar getBackStackEntryAt () . Para saber cuántas entradas tiene la actividad en la backstack, puede usar getBackStackEntryCount ()

 int lastFragmentCount = getBackStackEntryCount() - 1; 

En realidad, no hay un último fragmento agregado a la stack porque puede agregar varios o fragmentos a la stack en una sola transacción o simplemente eliminar fragmentos sin agregar uno nuevo.

Si realmente desea tener una stack de fragmentos y poder acceder a un fragmento por su índice en la stack, será mejor que tenga una capa de abstracción sobre el FragmentManager y su backstack. Así es cómo puedes hacerlo:

 public class FragmentStackManager { private final FragmentManager fragmentManager; private final int containerId; private final List fragments = new ArrayList<>(); public FragmentStackManager(final FragmentManager fragmentManager, final int containerId) { this.fragmentManager = fragmentManager; this.containerId = containerId; } public Parcelable saveState() { final Bundle state = new Bundle(fragments.size()); for (int i = 0, count = fragments.size(); i < count; ++i) { fragmentManager.putFragment(state, Integer.toString(i), fragments.get(i)); } return state; } public void restoreState(final Parcelable state) { if (state instanceof Bundle) { final Bundle bundle = (Bundle) state; int index = 0; while (true) { final Fragment fragment = fragmentManager.getFragment(bundle, Integer.toString(index)); if (fragment == null) { break; } fragments.add(fragment); index += 1; } } } public void replace(final Fragment fragment) { fragmentManager.popBackStackImmediate( null, FragmentManager.POP_BACK_STACK_INCLUSIVE); fragmentManager.beginTransaction() .replace(containerId, fragment) .addToBackStack(null) .commit(); fragmentManager.executePendingTransactions(); fragments.clear(); fragments.add(fragment); } public void push(final Fragment fragment) { fragmentManager .beginTransaction() .replace(containerId, fragment) .addToBackStack(null) .commit(); fragmentManager.executePendingTransactions(); fragments.add(fragment); } public boolean pop() { if (isEmpty()) { return false; } fragmentManager.popBackStackImmediate(); fragments.remove(fragments.size() - 1); return true; } public boolean isEmpty() { return fragments.isEmpty(); } public int size() { return fragments.size(); } public Fragment getFragment(final int index) { return fragments.get(index); } } 

Ahora, en lugar de agregar y eliminar fragmentos llamando directamente a FragmentManager , debe usar los métodos push() , replace() y pop() de FragmentStackManager . Y podrá acceder al fragmento superior simplemente llamando a stack.get(stack.size() - 1) .

Pero si te gustan los hacks, tengo otras formas de hacer cosas similares. Lo único que tengo que mencionar es que estos hacks funcionarán solo con fragmentos de soporte.

El primer truco es simplemente obtener todos los fragmentos activos agregados al administrador de fragmentos. Si solo reemplazas los fragmentos uno por uno y sacas los de la stack, este método devolverá el fragmento superior:

 public class BackStackHelper { public static List getTopFragments( final FragmentManager fragmentManager) { final List fragments = fragmentManager.getFragments(); final List topFragments = new ArrayList<>(); for (final Fragment fragment : fragments) { if (fragment != null && fragment.isResumed()) { topFragments.add(fragment); } } return topFragments; } } 

El segundo enfoque es el evento más hacky y le permite obtener todos los fragmentos agregados en la última transacción para la cual se ha llamado addToBackStack :

 package android.support.v4.app; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class BackStackHelper { public static List getTopFragments( final FragmentManager fragmentManager) { if (fragmentManager.getBackStackEntryCount() == 0) { return Collections.emptyList(); } final List fragments = new ArrayList<>(); final int count = fragmentManager.getBackStackEntryCount(); final BackStackRecord record = (BackStackRecord) fragmentManager.getBackStackEntryAt(count - 1); BackStackRecord.Op op = record.mHead; while (op != null) { switch (op.cmd) { case BackStackRecord.OP_ADD: case BackStackRecord.OP_REPLACE: case BackStackRecord.OP_SHOW: case BackStackRecord.OP_ATTACH: fragments.add(op.fragment); } op = op.next; } return fragments; } } 

Tenga en cuenta que en este caso debe colocar esta clase en el paquete android.support.v4.app .

Acabo de responder @roghayeh hosseini (correcto) y lo hice en Kotlin para aquellos aquí en 2017 🙂

 fun getTopFragment(): Fragment? { supportFragmentManager.run { return when (backStackEntryCount) { 0 -> null else -> findFragmentByTag(getBackStackEntryAt(backStackEntryCount - 1).name) } } } 

* Esto debe ser llamado desde dentro de una Actividad.

Disfruta 🙂

O simplemente puede agregar una etiqueta al agregar fragmentos correspondientes a su contenido y usar un campo String estático simple (también puede guardarlo en un paquete de instancia de actividad en el método SaveInstanceState (Bundle)) para mantener la última etiqueta de fragmento añadida y obtener este fragmento byTag () en cualquier momento que necesites …

La respuesta más alta (Deepak Goel) no funcionó bien para mí. De alguna manera, la etiqueta no se agregó correctamente.

Terminé simplemente enviando el ID del fragmento a través del flujo (usando intents) y recuperándolo directamente del administrador de fragmentos.