Trên thực tế, không có phân đoạn mới nhất nào được thêm vào ngăn xếp vì bạn có thể thêm một số hoặc các phân đoạn vào ngăn xếp trong một giao dịch duy nhất hoặc chỉ xóa các phân đoạn mà không thêm một đoạn mới.
Nếu bạn thực sự muốn có một chồng các phân đoạn và để có thể truy cập một phân đoạn bằng chỉ mục của nó trong ngăn xếp, tốt hơn bạn nên có một lớp trừu tượng trên FragmentManager
và backstack của nó. Đây là cách bạn có thể làm điều đó:
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);
}
}
Bây giờ thay vì thêm và loại bỏ các mảnh vỡ bằng cách gọi FragmentManager
trực tiếp, bạn nên sử dụng push()
, replace()
và pop()
phương pháp FragmentStackManager
. Và bạn sẽ có thể truy cập phân đoạn trên cùng chỉ bằng cách gọi stack.get(stack.size() - 1)
.
Nhưng nếu bạn thích hack, tôi phải làm những cách khác tương tự. Điều duy nhất tôi phải đề cập là các bản hack này sẽ chỉ hoạt động với các mảnh hỗ trợ.
Lần hack đầu tiên chỉ là để thêm tất cả các phân mảnh đang hoạt động vào trình quản lý phân mảnh. Nếu bạn chỉ thay thế từng đoạn một và bật từ ngăn xếp, phương pháp này sẽ trả về đoạn trên cùng:
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;
}
}
Cách tiếp cận thứ hai là sự kiện phức tạp hơn và cho phép bạn nhận được tất cả các phân đoạn được thêm vào trong giao dịch cuối cùng addToBackStack
được gọi là:
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;
}
}
Xin lưu ý rằng trong trường hợp này, bạn phải đặt lớp này vào android.support.v4.app
gói.
FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
hoặcFragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
doc