Tatsächlich wird dem Stapel kein aktuelles Fragment hinzugefügt, da Sie mehrere oder Fragmente in einer einzigen Transaktion zum Stapel hinzufügen oder einfach Fragmente entfernen können, ohne ein neues hinzuzufügen.
Wenn Sie wirklich einen Fragmentstapel haben möchten und über seinen Index im Stapel auf ein Fragment zugreifen können möchten, sollten Sie eine Abstraktionsschicht über dem FragmentManager
und seinem Backstack haben. So geht's:
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);
}
}
Anstatt nun das Hinzufügen und Fragmente durch den Aufruf zu entfernen FragmentManager
direkt, sollten Sie verwenden push()
, replace()
und pop()
Methoden FragmentStackManager
. Und Sie können auf das oberste Fragment zugreifen, indem Sie einfach anrufenstack.get(stack.size() - 1)
.
Aber wenn Sie Hacks mögen, habe ich andere Möglichkeiten, ähnliche Dinge zu tun. Das einzige, was ich erwähnen muss, ist, dass diese Hacks nur mit Support-Fragmenten funktionieren.
Der erste Hack besteht darin, alle aktiven Fragmente zum Fragmentmanager hinzuzufügen. Wenn Sie nur Fragmente einzeln ersetzen und die vom Stapel entfernen, gibt diese Methode das oberste Fragment zurück:
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;
}
}
Der zweite Ansatz ist ereignisreicher und ermöglicht es Ihnen, alle Fragmente der letzten Transaktion hinzuzufügen, für die Folgendes addToBackStack
aufgerufen wurde:
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;
}
}
Bitte beachten Sie, dass Sie in diesem Fall diese Klasse in ein android.support.v4.app
Paket packen müssen.
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
oderFragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
doc