FragmentTransaction:replace和addToBackStack不能一起工作?
我对Android开发相当陌生,现在运行起来怪异的行为。FragmentTransaction:replace和addToBackStack不能一起工作?
- 我有一个空的FrameLayout是一个片段的容器。
- 如果用户第一次按下按钮,生成新的碎片并放入容器中。
- 如果稍后用户按下某个按钮,并且容器中存在现有的片段,请将现有片段替换为新生成的片段。
- 如果用户按回按钮,弹出容器内的片段。
这里是我的代码
public void showFragment(View v) {
FragmentA f = new FragmentA();
FragmentManager fm = getSupportFragmentManager();
String tag = f.getFragmentTag(); // instance method of a to get a tag
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_top, 0, 0, R.anim.slide_out_top);
ft.replace(R.id.container, f, tag);
ft.addToBackStack(tag);
ft.commit();
}
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
当用户按下按钮,第一次,它表现得像我所料,添加新的片段容器。但是,第二次用户按下按钮时,容器仍然包含一个片段,而不是替换,它会在现有的顶部添加一个新的。 因此,2个容器内的碎片,2个后退按钮去除所有碎片。
我发现,如果我删除行
ft.addToBackStack();
和返工的onBackPress()方法等之后,它再次工作方式类似于我预期(1个容器在一个时间片段)
基本上,手动删除而不是popFromBackStack方法
private FragmentA currentFragment = null; // to hold the reference to exising fragment, if any.
@Override
public void onBackPressed() {
if (currentFragment != null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(0, R.anim.slide_out_top);
ft.remove(currentFragment);
ft.commit();
currentFragment = null;
} else {
super.onBackPressed();
}
}
所以片段,我questio n分别是
- replace和addToBackStack是不是在一起工作?
- 或者,我做错了什么?
感谢所有的意见和建议。
addToBackstack
创建碎片状态的快照。这意味着当你按下后退按钮时,你实际上会回到addToBackstack
被调用的最后一个状态。
在你的情况下,你添加一个片段。后退按钮将删除此添加的片段。当你调用replace时,再次添加到backstack中时,你现在在后台有两个状态(1.当你添加了第一个片段时,2.当你没有添加片段时)。如果你后退按钮删除当前片段,则不要使用addToBackstack。只有在想要保留视图中片段的状态时才使用addToBackstack。
嗨Spidy,感谢您的评论。我仍然很困惑,但我可以说,在我的情况下,我不应该使用addToBackStack? –
是的,它听起来像你不需要addToBackstack你的用例 – Spidy
@Spidy在Android开发人员网站https://developer.android.com/training/implementing-navigation/temporal.html#back-fragments他们说,您应该使用addToBackStack在片段之间导航时提供正确的后退导航。你有什么理由不使用它们? 和2:“在你的情况下,你添加一个Fragment,后退按钮将删除这个添加的片段,当你调用replace时,再次添加到backstack,你现在有两个状态在backstack上。在他的代码中他添加了一个片段?我只看到replace() – Rule
对于那些仍在寻找解决方案的人。
在主Activity
类(它是主办片段)只是覆盖onBackPressed()
。
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
中有片段没有onBackPressed()
方法,而这种方法只是为了activity
。所以,当我们按下返回键,中activity
默认行为所示,这是
你要么去之前的活动(如果有的话)或应用 将退出。
现在我们需要重写这个方法告诉activity
,当我们按下返回键,如果在后面堆栈中的任何片段,弹出出来(这是当addToBackStack()
进入图片)。否则,请遵循默认行为。
找到更多的细节在这里here
我想这就是原因: “如果你不叫addToBackStack()当您进行交易,消除片段,则该片段是当事务提交销毁并且用户不能导航回去,而如果在删除片段时确实调用了addToBackStack(),则该片段将停止,并且如果用户返回,将会恢复。 当您使用addToBackStack()时,以前的片段将停止并保留。 请参阅:https://developer.android.com/guide/components/fragments.html#Transactions –