我已经意识到这个问题之前已经被问过,但是之前的答案到目前为止已经得到了我的答案。方案如下:我们有一个仪表板片段(A),它将用户引导到登录屏幕(B)。成功登录后,他们会转到列表视图(c)。在背压上我想返回A,因为用户不需要再次看到登录屏幕。此外,在成功登录后,我们将详细信息存储在共享首选项中,并在下次自动登录B,这一切都按计划进行。
我有以下FragmentHelper方法:
public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx)
{
// Create new fragment and transaction
FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(container, fragment);
if(addToBackStack)
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
在从B到C的事务中,我将布尔addToBackStack设置为false,以便不调用transaction.addToBackStack(null);
。这再次运作良好,但之后我的问题开始了。
当用户按下C并返回A时,我仍然可以在A的视图下看到C的膨胀视图。
任何帮助将不胜感激。我希望我的图表有助于保持这一点。
答案 0 :(得分:21)
我在一条线内解决了这个......
getFragmentManager().popBackStack();
或
getSupportFragmentManager().popBackStack()
当你添加片段并维护backstack(不替换)时,这是有效的。
答案 1 :(得分:6)
f1 - > F2
Fragment2 f2 = new Fragment2();
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit();
这里没什么特别的。在片段f2中,此代码将您带到片段f3。
f2 - > F3
Fragment3 f3 = new Fragment3();
getActivity().getSupportFragmentManager().popBackStack();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();
我不确定通过阅读文档是否应该有效,这种弹出的事务方法据说是异步的,也许更好的方法是调用popBackStackImmediate()。但到目前为止,我可以在我的设备上告诉它它的工作完美无瑕。
上述替代方案将是:
final FragmentActivity activity = getActivity();
activity.getSupportFragmentManager().popBackStackImmediate();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();
这里实际上会有短暂的回到f1 beofre继续前进到f3,所以那里有轻微的故障。
这实际上是你所要做的,这个answer也可以帮助你......
答案 2 :(得分:1)
有几种方法可以解决这个问题:
我在我的应用程序中有类似的流程,我解决它的方法是使用从主活动触发的AlertDialog替换登录片段。 所以在你的情况下,片段A出现在屏幕上,如果主要活动认为它需要显示登录对话框,它会显示AlertDialog。这对我有用。
当启用片段A时,它可以通过询问FragmentManager来检查片段C是否在周围。如果存在则将其删除。
答案 3 :(得分:0)
没有告诉FM您希望从B到C的转换添加到backStack意味着当您回击时,FM没有添加C的记录,因此它不会将其删除。
答案 4 :(得分:0)
步骤1:当您在片段A中并且想要打开片段B
时getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentB(), FragmentB.class.getName()
.addToBackStack(null)
.commit();
步骤2:当你在Fragment B中时,想要打开Fragment C
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new FragmentC(), FragmentC.class.getName()
.disallowAddToBackStack() // << this to make Fragment B, not included in the backstack
.commit();
步骤3:当您在片段C中,按设备后退按钮或getFragmentManager().popBackStack();
时,您将打开片段A。
PS:在活动中使用此getSupportFragmentManager()
。如果您在片段中,请使用此getFragmentManager()
答案 5 :(得分:0)
您好,我只想分享我找到的优雅解决方案。
public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) {
final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1;
fragmentManager.beginTransaction()
.replace(R.id.content, fragment, tag)
.addToBackStack(tag)
.commit();
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
int nowCount = fragmentManager.getBackStackEntryCount();
if (newBackStackLength != nowCount) {
// we don't really care if going back or forward. we already performed the logic here.
fragmentManager.removeOnBackStackChangedListener(this);
if ( newBackStackLength > nowCount ) { // user pressed back
fragmentManager.popBackStackImmediate();
}
}
}
});
}