【发布时间】:2014-01-07 12:40:06
【问题描述】:
我对 Android 开发还很陌生,现在遇到了奇怪的行为。
- 我有一个空 FrameLayout 作为片段的容器。
- 如果用户第一次按下按钮,则生成新的 Fragment 并放入容器中。
- 如果用户稍后按下按钮并且容器内有现有片段,请将现有片段替换为新生成的片段。
- 如果用户按下返回按钮,弹出容器内的片段。
这是我的代码
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();
}
}
所以,我的问题是
- replace 和 addToBackStack 不能一起工作?
- 或者,我做错了什么?
感谢所有 cmets 和建议。
【问题讨论】:
-
我认为这就是原因:“如果您在执行删除片段的事务时不调用 addToBackStack() ,那么当提交事务并且用户无法返回时,该片段将被销毁然而,如果您在删除片段时确实调用了 addToBackStack(),那么片段将停止,并且如果用户导航回来,它将恢复。”当您使用 addToBackStack() 时,先前的片段将停止并保留。见:developer.android.com/guide/components/…
标签: android android-fragments fragmenttransaction