Android FragmentManager popBackStack 不会删除片段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23499198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
FragmentManager popBackStack doesn't remove fragment
提问by edrian
I'm implementing menu navigation using Fragments. So I begin with Home, and then users can navigate to diferent sections and details of each section.
我正在使用 Fragments 实现菜单导航。所以我从首页开始,然后用户可以导航到不同的部分和每个部分的详细信息。
When a user changes section, then I call pop on the fragmentmanager backstack until I reach Home, and then load the new section.
当用户更改部分时,我会在 fragmentmanager backstack 上调用 pop 直到我到达 Home,然后加载新部分。
This is all working as expected. But I'm getting this problem:
这一切都按预期工作。但我遇到了这个问题:
- load a section that calls setHasOptionsMenu(true) on onResume()
- loads another section (old section it's suposed to get out of the stack). I see it OK. No menu is shown
- leave the application (for example, go to Android Laucher activity) and then when I return, I see the correct section, but it's showing the Menu of the old Fragment.
- 加载在 onResume() 上调用 setHasOptionsMenu(true) 的部分
- 加载另一个部分(旧部分应该退出堆栈)。我看没问题。没有显示菜单
- 离开应用程序(例如,转到 Android Laucher 活动),然后当我返回时,我看到了正确的部分,但它显示的是旧片段的菜单。
I've iterated the backstack and printed each fragment, and there it's not the fragment with the menu.
我已经迭代了 backstack 并打印了每个片段,但它不是带有菜单的片段。
I put a debug mark on the onResume() method (where the setHasOptionsMenu(true)
is flagged) and it indeed enters here, so the Fragment it's still somewhere.
我在 onResume() 方法上放了一个调试标记(setHasOptionsMenu(true)
标记的地方),它确实进入了这里,所以 Fragment 它仍然在某处。
I want to know if I'm doing something wrong and how could I solve it, thx
我想知道我是否做错了什么,我该如何解决,谢谢
Update:
更新:
I'm using this code to load new fragments
我正在使用此代码加载新片段
fm.beginTransaction()
.add(container, sectionFragment.getFragment())
.addToBackStack(sectionFragment.getFragmentName())
.commit();
And for remove:
并删除:
private void clearStack(){
int count = fm.getBackStackEntryCount();
while(count > 1){
fm.popBackStack();
count--;
}
}
NOTE 1:I'm using add instead replace because I don't want to loose the state of my fragment when I navigate back from detail section. When I load another different section, then I call clearStack to pop the stack up to 1, and then loads new fragment. At the end, I'm calling executePendingTransactions() to finish to remove the fragments from the transaction.
注意 1:我使用添加而不是替换,因为当我从详细信息部分导航回来时,我不想丢失片段的状态。当我加载另一个不同的部分时,我调用 clearStack 将堆栈弹出到 1,然后加载新片段。最后,我调用 executePendingTransactions() 来完成从事务中删除片段。
NOTE 2:I'm seeing that it is entering on my fragment onDestroy() method, so it is suposed to be destroyed. But I don't know why it is getting called again when the Main activity resumes.
注意 2:我看到它正在进入我的片段 onDestroy() 方法,因此它应该被销毁。但是我不知道为什么在 Main 活动恢复时它会再次被调用。
回答by edrian
I found that the problem was not in the logic of adding and removing fragment of the stack.
我发现问题不在于添加和删除堆栈片段的逻辑。
The problem was that some of the fragment loaded another fragments inside of it (it had ViewPager component). Then I thought that when the fragment was removed then these fragments were removed too.
问题是某些片段在其中加载了另一个片段(它具有 ViewPager 组件)。然后我想,当片段被删除时,这些片段也被删除了。
This is true ONLY if you use getChildFragmentManager()
method. This method MUST be used when loading fragments inside other fragmets. If not, then the fragments are asociated with the fragments activity.
仅当您使用getChildFragmentManager()
方法时,这才是正确的。在其他片段中加载片段时,必须使用此方法。如果不是,则片段与片段活动相关联。
回答by Malder
I found this question, because after calling
我发现了这个问题,因为在打电话之后
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
this code fragmentManager.getFragments().size()
returns the maximum number of fragments me, that were in the stack. I checked every fragment on null. And I found that some fragment is null on my case. Maybe it will help to somebody)
此代码fragmentManager.getFragments().size()
返回堆栈中的最大片段数。我检查了 null 上的每个片段。我发现我的案例中有一些片段是空的。也许它会对某人有所帮助)
回答by Neige
popBackStack
will just revert your last FragmentTransaction
.
popBackStack
只会恢复你的最后一个FragmentTransaction
.
If you use FragmentTransaction.add
, popBackStack
will just call FragmentTransacetion.remove
.
如果你使用FragmentTransaction.add
,popBackStack
只会调用FragmentTransacetion.remove
。
But if you call FragmentTransaction.replace
, popBackStack
will call FragmentTransaction.remove
and FragmentTransaction.add
但是如果你打电话FragmentTransaction.replace
,popBackStack
会打电话FragmentTransaction.remove
和FragmentTransaction.add
For your "NOTE 1" :
FragmentTransaction.replace
will not change your fragment state.
对于您的“注意 1”:
FragmentTransaction.replace
不会改变您的片段状态。
回答by Aviv Cohen
I had a similar problem where the popBackStack()
didn't remove my fragment.
However, I noticed that I called the wrong FragmentManager
, where I had to call getSupportFragmentMananger()
instead of getFragmentManager()
.
我有一个类似的问题,popBackStack()
没有删除我的片段。但是,我注意到我调用了错误的FragmentManager
,我不得不调用getSupportFragmentMananger()
而不是getFragmentManager()
.
回答by zIronManBox
If you are really looking to remove fragments at once then follow: How to replace Fragments of different types?
如果您真的想立即删除片段,请遵循: 如何替换不同类型的片段?
Otherwise use replace transaction for fragments to smooth transitiona and hassel free approach, see https://stackoverflow.com/a/23013075/3176433
否则使用替换事务片段来平滑过渡和无障碍方法,请参阅https://stackoverflow.com/a/23013075/3176433
Also understand Fragment lifecycle, http://developer.android.com/guide/components/fragments.html
也了解 Fragment 生命周期, http://developer.android.com/guide/components/fragments.html