En realidad, no se ha agregado el último fragmento a la pila porque puede agregar varios o fragmentos a la pila en una sola transacción o simplemente eliminar fragmentos sin agregar uno nuevo.
Si realmente desea tener una pila de fragmentos y poder acceder a un fragmento por su índice en la pila, será mejor que tenga una capa de abstracción sobre FragmentManager
y su backstack. Así es como puede hacerlo:
public class FragmentStackManager {
private final FragmentManager fragmentManager;
private final int containerId;
private final List<Fragment> 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 quitar fragmentos llamando FragmentManager
directamente, se debe utilizar push()
, replace()
y pop()
los métodos de FragmentStackManager
. Y podrá acceder al fragmento superior simplemente llamando stack.get(stack.size() - 1)
.
Pero si te gustan los trucos, tengo otras formas de hacer cosas similares. Lo único que tengo que mencionar es que estos trucos funcionarán solo con fragmentos de soporte.
El primer truco es simplemente agregar todos los fragmentos activos al administrador de fragmentos. Si solo reemplaza los fragmentos uno por uno y los saca de la pila, este método devolverá el fragmento superior:
public class BackStackHelper {
public static List<Fragment> getTopFragments(
final FragmentManager fragmentManager) {
final List<Fragment> fragments = fragmentManager.getFragments();
final List<Fragment> topFragments = new ArrayList<>();
for (final Fragment fragment : fragments) {
if (fragment != null && fragment.isResumed()) {
topFragments.add(fragment);
}
}
return topFragments;
}
}
El segundo enfoque es event more hacky y le permite obtener todos los fragmentos agregados en la última transacción para la que addToBackStack
se ha llamado:
package android.support.v4.app;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BackStackHelper {
public static List<Fragment> getTopFragments(
final FragmentManager fragmentManager) {
if (fragmentManager.getBackStackEntryCount() == 0) {
return Collections.emptyList();
}
final List<Fragment> 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 poner esta clase en el android.support.v4.app
paquete.
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
oFragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
doc