在我的开源Android应用中,发现了一个问题,即某个特定片段会在另一个片段的顶部进入视图,或者在特定情况下使应用崩溃。
如果您想查看更多信息和示例屏幕截图,请访问GitHub: https://github.com/rpi-mobile/RPIMobile-Android/issues/31
我已经确定了原因,但想知道android.support.v4.app包中的哪些方法用于解决问题。
在MainActivity.java
中,是使用FragmentTransaction.replace()
切换片段的导航抽屉的代码。
问题出现了,因为在MapFragment
中,我使用了:
ViewMapFragment vmf = new ViewMapFragment();
FragmentTransaction ft = getSherlockActivity().getSupportFragmentManager().beginTransaction();
ft.addToBackStack(null);
ft.replace(R.id.content_frame, vmf);
ft.commit();
在ViewMapFragment
' s onDestroyView()
:
FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fm.findFragmentById(R.id.mapview));
ft.commit();
onDestroyView()
从视图中正确删除ViewMapFragment
,但是如果您在视图中使用它并使用导航抽屉更改为其他片段,则MapFragment
仍在后台
所以,对于我的问题:
1)在尝试删除/替换特定片段之前,如何检查特定片段是否在后端堆栈上,如果没有任何东西(即不检查),应用程序是否会崩溃?例如。当后台堆栈上什么都没有时调用popBackStack()
。
2)我应该使用FragmentManager
类方法尝试从后台堆栈中删除MapFragment
,还是应该使用FragmentTransaction
方法?优点与缺点?
3)popBackStack()
和popBackStackImmediate()
之间的界面有何不同?用户是否看到了一些毛病的过渡?
答案 0 :(得分:4)
根据FragmentTransaction的文档,当您调用addToBackStack方法时,它只会记住您在该事务中执行的操作。当调用popBackStack方法时,它将反转这些操作并执行它们。
那么,会发生什么:
有几种方法可以处理这种情况:
要清除堆栈,您可以使用此代码(related question):
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
如果您将此行放在selectItem方法的开头,则会修复错误。
您的问题:
实施例。例如,我们添加了一个标签为“fragment-1”的片段:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame, new TestFragment(), "fragment-1")
.commit();
然后,我们将它放入后台堆栈并将其替换为另一个片段:
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.frame, new TestFragment(), "another-fragment")
.commit();
此时getSupportFragmentManager()。findFragmentByTag(“fragment-1”)返回我们的第一个片段(它从后栈条目中获取)。现在我们可以通过isAdded方法检查这个片段是否被添加到它的活动中 - 如果它返回false,那么我们可以假设片段在后面的堆栈中。