其實有添加到堆棧,因爲你可以在一個事務中增加幾個或片段堆棧或只是刪除片段無需添加一個新的無最新片段。
如果你確實想要一堆碎片,並且能夠通過堆棧中的索引來訪問碎片,那麼最好在FragmentManager
及其後臺上有一個抽象層。這裏是你如何能做到這一點:
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);
}
}
現在不是增加並通過直接調用FragmentManager
除去碎片,你應該使用的FragmentStackManager
push()
,replace()
和pop()
方法。您只需撥打stack.get(stack.size() - 1)
即可訪問最上面的片段。
但是,如果你喜歡黑客,我不得不採取其他方式做類似的事情。我必須提到的唯一事情就是這些黑客只會在支持碎片的情況下才能使用。
第一個破解就是將所有活動片段添加到片段管理器中。如果你只是更換片段逐個彈出從堆棧此方法將返回最上面的片段:
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;
}
}
第二種方法是事件的詳細哈克,並允許您在最後交易得到補充的所有片段的這addToBackStack
被稱爲:
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;
}
}
請注意,在這種情況下,你必須把這個類轉換android.support.v4.app
包。
但是我怎樣才能得到最後一個片段在後臺? popBackStackEntryAt()只返回一個BackStackEntry實例,不是片段 – 2012-03-14 12:53:25
是的,你是對的,但是每個BackStackEntry都存在,你可以通過getId()返回id。您可以使用此Id以檢索片段 – Blackbelt 2012-03-14 12:55:44
獲取最後一個片段:getBackStackEntryCount() - 1 – 2013-04-08 09:12:18