Sebenarnya tidak ada fragmen terbaru yang ditambahkan ke tumpukan karena Anda dapat menambahkan beberapa atau fragmen ke tumpukan dalam satu transaksi atau hanya menghapus fragmen tanpa menambahkan yang baru.
Jika Anda benar-benar ingin memiliki tumpukan fragmen dan dapat mengakses fragmen berdasarkan indeksnya di tumpukan, Anda sebaiknya memiliki lapisan abstraksi di atas FragmentManager
dan backstacknya. Inilah cara Anda melakukannya:
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);
}
}
Sekarang bukan menambah dan menghapus fragmen dengan menelepon FragmentManager
langsung, Anda harus menggunakan push()
, replace()
dan pop()
metode FragmentStackManager
. Dan Anda akan dapat mengakses fragmen paling atas hanya dengan menelepon stack.get(stack.size() - 1)
.
Tetapi jika Anda suka retas, saya harus cara lain untuk melakukan hal serupa. Satu-satunya hal yang harus saya sebutkan adalah bahwa peretasan ini hanya akan berfungsi dengan fragmen dukungan.
Peretasan pertama hanya untuk menambahkan semua fragmen aktif ke pengelola fragmen. Jika Anda hanya mengganti fragmen satu per satu dan mengeluarkannya dari tumpukan, metode ini akan mengembalikan fragmen paling atas:
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;
}
}
Pendekatan kedua adalah event more hacky dan memungkinkan Anda untuk mendapatkan semua fragmen yang ditambahkan dalam transaksi terakhir yang addToBackStack
telah dipanggil:
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;
}
}
Harap perhatikan bahwa dalam hal ini Anda harus memasukkan kelas ini ke dalam android.support.v4.app
paket.
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
atauFragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
dok