【发布时间】:2014-03-07 02:01:12
【问题描述】:
我的导航抽屉中列出了许多页面/片段,用户可能会经常在这些页面/片段之间切换,我希望它们在后台堆栈中以便他们可以导航回来,但我只想要每个片段的一个实例后台堆栈,这样用户就不必疯狂地按回很多次来退出应用程序。我不知道如何在不删除页面的情况下有效地“重新排序”backstack。
目前,当我更改页面时,我正在使用此代码更改片段并确保它仅在后堆栈中一次
if (mFragMgr == null) {
mFragMgr = getSupportFragmentManager();
}
String backStateName = fragmentDescriptor.name();
boolean fragmentPopped = mFragMgr.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped){
mFragMgr.beginTransaction()
.remove((Fragment) mFragment)
.replace(R.id.content_frame, (Fragment) mFragment)
.addToBackStack(backStateName)
.commit();
}
我在 onBackPressed 中使用此代码
@Override
public void onBackPressed() {
if (mFragMgr.getBackStackEntryCount() > 0) {
mFragMgr.popBackStackImmediate();
} else {
super.onBackPressed();
}
}
这可行,但这意味着它会删除我不想删除的页面。示例:
当我的用户按 A > B > C > D > E > C 的顺序访问 6 个页面时,因为我正在执行删除操作,我预计会出现以下堆栈:
[E] [C]
[D] [D] [E]
[C] [C] [C] [D]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
但我实际上得到的是以下内容 - 它会将所有内容弹出到与名称匹配的元素,这与我是否包含“.remove((Fragment) mFragment)”无关 - (I '现在已经意识到 remove 不会影响 backstack,所以无需指出这一点):
[E]
[D] [D]
[C] [C] [C] [C]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
如果我在添加到后台堆栈时不使用名称而是使用 null,我会得到以下信息:
[C]
[E] [E]
[D] [D] [D]
[C] [C] [C] [C]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
我怎样才能得到我期望的行为?是否有可能,还是我需要自己记录更改并完全跳过后台堆栈?
【问题讨论】:
-
我正在尝试找到一种有效的方法来解决这个问题,我在我的问题上付出了一些努力 - 如果投票的人有勇气说出原因,那就太好了
-
抱歉,
FragmentManagerAPI 中没有用于从后台堆栈中间移除Fragment状态的方法。 API 仅公开了用于推送和弹出的标准堆栈机制。 -
我认为可能是这样。但我的用例似乎是一个非常有效、相当普遍的需求,您可以通过活动实现类似的需求。我希望有人可能知道帮助类或实现此目的的东西
-
好吧,我不知道任何现有的解决方案,也不能不使用反射或自定义
FragmentManager实现来实现。如果您愿意这样做,那么它实际上应该很容易实现。 -
我想应该可以手动创建您自己的自定义
Fragment回栈,使用您需要的任何功能。您将无法使用BackStackRecord类,因为它取决于堆栈模型;它必须是一个定制的解决方案。如果您有兴趣,那么我可能会在几天内有时间(或者其他人可以)写一个基于此的答案。或者,如果您愿意,您也可以自己尝试——应该不会太难。
标签: android android-fragments back-stack