16

我正在使用 Fragments 实现菜单导航。所以我从主页开始,然后用户可以导航到不同的部分和每个部分的详细信息。

当用户更改部分时,我在 fragmentmanager backstack 上调用 pop 直到我到达 Home,然后加载新部分。

这一切都按预期工作。但我遇到了这个问题:

  1. 在 onResume() 上加载调用 setHasOptionsMenu(true) 的部分
  2. 加载另一个部分(它应该从堆栈中取出的旧部分)。我看还行。没有显示菜单
  3. 离开应用程序(例如,转到 Android Laucher 活动),然后当我返回时,我看到了正确的部分,但它显示的是旧片段的菜单。

我已经迭代了 backstack 并打印了每个片段,它不是带有菜单的片段。

我在 onResume() 方法(标记的地方)上放了一个调试标记setHasOptionsMenu(true),它确实进入了这里,所以 Fragment 它仍然在某个地方。

我想知道我是否做错了什么以及如何解决它,谢谢

更新:

我正在使用此代码加载新片段

fm.beginTransaction()
    .add(container, sectionFragment.getFragment())
    .addToBackStack(sectionFragment.getFragmentName())
    .commit();

并删除:

private void clearStack(){
int count = fm.getBackStackEntryCount();
    while(count > 1){
        fm.popBackStack();
        count--;
    }
}

注意 1:我使用 add 而不是 replace 因为我不想在从详细信息部分返回时丢失片段的状态。当我加载另一个不同的部分时,我调用 clearStack 将堆栈弹出到 1,然后加载新片段。最后,我调用 executePendingTransactions() 来完成从事务中删除片段。

注意 2:我看到它正在进入我的片段 onDestroy() 方法,因此它应该被销毁。但我不知道为什么在 Main 活动恢复时它会再次被调用。

4

6 回答 6

24

我发现问题不在于添加和删除堆栈片段的逻辑。

问题是某些片段在其中加载了另一个片段(它具有 ViewPager 组件)。然后我想当片段被移除时,这些片段也被移除了。

仅当您使用getChildFragmentManager()方法时才适用。在其他片段中加载片段时必须使用此方法。如果不是,则片段与片段活动相关联。

于 2014-05-06T17:15:45.967 回答
7

我发现了这个问题,因为打电话后

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

此代码fragmentManager.getFragments().size() 返回堆栈中的最大片段数。我检查了 null 上的每个片段。而且我发现某些片段在我的情况下是空的。也许它会帮助某人)

于 2015-03-09T15:44:27.677 回答
6

popBackStack只会恢复你的最后一个FragmentTransaction.

如果你用FragmentTransaction.addpopBackStack只会打电话FragmentTransacetion.remove

但是如果你打电话FragmentTransaction.replacepopBackStack会打电话FragmentTransaction.removeFragmentTransaction.add

对于您的“注意 1”: FragmentTransaction.replace不会改变您的片段状态。

于 2014-05-06T16:14:06.413 回答
0

如果您真的想立即删除片段,请遵循: 如何替换不同类型的片段?

否则,使用片段替换事务来平滑过渡a 和无麻烦的方法,请参阅https://stackoverflow.com/a/23013075/3176433

也了解 Fragment 生命周期, http://developer.android.com/guide/components/fragments.html

于 2014-05-06T16:11:13.740 回答
0

也许有一个<fragment><androidx.fragment.app.FragmentContainerView>在一个活动中android:name="androidx.navigation.fragment.NavHostFragment",app:defaultNavHost="true"app:navGraph="@navigation/nav_graph"

在这种情况下,导航由 持有nav_graph。如果您不想使用NavControllerand NavHostFragment,也许您应该删除导航和清洁<fragment>标签。

于 2020-11-29T20:33:52.277 回答
0

我有一个类似的问题,popBackStack()没有删除我的片段。但是,我注意到我打错了FragmentManager,我不得不打电话getSupportFragmentMananger()而不是getFragmentManager()

于 2018-03-09T13:34:13.167 回答