[英]Proper/Best Way to Handle Android Fragment Transaction Issue
In my open source Android app, an issue has been discovered where a specific fragment will come into view on top of another fragment or crash the app in a certain situation. 在我的开源Android应用程序中,已发现一个问题,即某个特定片段将在另一个片段之上进入视图或在某种情况下使应用程序崩溃。
The issue on GitHub if you want to see more information and example screenshots: https://github.com/rpi-mobile/RPIMobile-Android/issues/31 如果您想查看更多信息和示例屏幕截图,请访问GitHub: https : //github.com/rpi-mobile/RPIMobile-Android/issues/31
I have pinned down the reason, but want to know which of the methods in the android.support.v4.app package to use to resolve the issue. 我已经确定了原因,但想知道android.support.v4.app包中的哪些方法用于解决问题。
In MainActivity.java
, is the code for the navigation drawer that uses FragmentTransaction.replace()
to switch fragments. 在MainActivity.java
,是导航抽屉的代码,它使用FragmentTransaction.replace()
来切换片段。
The issue arises because in MapFragment
, I use: 问题出现了,因为在MapFragment
,我使用:
ViewMapFragment vmf = new ViewMapFragment();
FragmentTransaction ft = getSherlockActivity().getSupportFragmentManager().beginTransaction();
ft.addToBackStack(null);
ft.replace(R.id.content_frame, vmf);
ft.commit();
And in ViewMapFragment
's onDestroyView()
: 在ViewMapFragment
的onDestroyView()
:
FragmentManager fm = getSherlockActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fm.findFragmentById(R.id.mapview));
ft.commit();
The onDestroyView()
properly removes the ViewMapFragment
from view, but if you have it in view and use the navigation drawer to change to a different fragment, MapFragment
is still on the back stack. onDestroyView()
从视图中正确删除ViewMapFragment
,但如果您在视图中使用它并使用导航抽屉更改为其他片段,则MapFragment
仍在后台堆栈中。
So, for my questions: 所以,对于我的问题:
1) How do I check if a particular fragment is on the back stack before attempting to remove/replace it, or will the app not crash if you attempt when nothing is there (ie not checking)? 1)如何在尝试删除/替换特定片段之前检查特定片段是否在后端堆栈上,或者如果您尝试什么也没有(即不检查),应用程序是否会崩溃? Eg calling popBackStack()
when there is nothing on the back stack. 例如,当后台堆栈上没有任何内容时调用popBackStack()
。
2) Should I use FragmentManager
class methods to attempt to remove the MapFragment
from the back stack or should I use FragmentTransaction
methods? 2)我应该使用FragmentManager
类方法尝试从后栈中删除MapFragment
还是应该使用FragmentTransaction
方法? Pros vs cons? 优点与缺点?
3) What is the difference in the UI between popBackStack()
and popBackStackImmediate()
? 3) popBackStack()
和popBackStackImmediate()
之间的UI有什么区别? Does the user see some glitchy transitions? 用户是否看到了一些毛病的过渡?
According to the documentation of FragmentTransaction , when you invoke addToBackStack method it just remembers what actions you perform in that transaction. 根据FragmentTransaction的文档,当您调用addToBackStack方法时,它只会记住您在该事务中执行的操作。 When popBackStack method is invoked it will reverse those actions and execute them. 当调用popBackStack方法时,它将反转这些操作并执行它们。
So, what happens: 那么,会发生什么:
There is several options to handle such a situation: 有几种方法可以处理这种情况:
To clear back stack you can use this code ( related question ): 要清除堆栈,您可以使用此代码( 相关问题 ):
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
If you put this line in the beginning of your selectItem method the bug will be fixed. 如果将此行放在selectItem方法的开头,则会修复错误。
And your questions: 还有你的问题:
Example. 例。 For instance, we have added a fragment with tag "fragment-1": 例如,我们添加了一个标签为“fragment-1”的片段:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame, new TestFragment(), "fragment-1")
.commit();
Then, we put it into a back stack and replace it with another fragment: 然后,我们将它放入后台堆栈并用另一个片段替换它:
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.frame, new TestFragment(), "another-fragment")
.commit();
At this point getSupportFragmentManager().findFragmentByTag("fragment-1") returns our first fragment (it gets it from a back stack entry). 此时,getSupportFragmentManager()。findFragmentByTag(“fragment-1”)返回我们的第一个片段(它从后栈条目中获取)。 Now we can check whether this fragment is added to its activity by isAdded method - if it returns false, then we can make an assumption that the fragment is in a back stack. 现在我们可以通过isAdded方法检查这个片段是否被添加到它的活动中 - 如果它返回false,那么我们可以假设片段在后面的堆栈中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.