0

我有一个带有片段容器和 NavigationDrawer 的活动。如果我选择抽屉中的一个项目,我会调用updatePage(index).

updatePage(0)如果我创建活动并启动我的活动,我也会打电话savedInstanceState == null

一个片段有一个子片段,因此它只是用子片段替换自己并将子片段添加到后台堆栈,以便用户可以导航回前一个片段。在这个片段中,我直接调用以下代码:

@Override
public void onClick(View view)
{
    Event event = (Event)view.getTag();

    FragmentManager fm = getActivity().getSupportFragmentManager();

    GamesFragment f = new GamesFragment();

    Bundle bundle = new Bundle();
    bundle.putParcelable(GamesFragment.KEY_EVENT, event);
    f.setArguments(bundle);

    FragmentTransaction ft = fm.beginTransaction()
            .replace(R.id.frame_container, f, f.getClass().getName())
            .addToBackStack(null);
    ft.commit();
}

为什么有时删除旧片段不起作用?我得到重叠的片段,但只是有时。

我的活动updatePage功能如下所示:

private void updatePage(int drawerSelection)
{
    mDrawer.closeDrawer();

    Fragment f = null;
    FragmentManager fm = getSupportFragmentManager();

    switch (drawerSelection)
    {
        case 0:
            f = fm.findFragmentByTag(HomeFragment.class.getName());
            if (f == null)
                f = new HomeFragment();
            break;
        case 1:
            f = fm.findFragmentByTag(EventFragment.class.getName());
            if (f == null)
                f = new EventFragment();
            break;
        default:
            break;
    }

    if (f != null && !f.isAdded())
    {
        // SOLUTION:
        // Backstack clearen
        // fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.frame_container, f, f.getClass().getName());
        ft.commit();
    }
}
4

2 回答 2

1

这种情况我见过几次,我敢打赌用 addToBackStack 替换后会发生这种情况。最简单的解决方法是为片段布局添加背景。来自安卓文档:

注意:当您移除或替换一个片段并将事务添加到后台堆栈时,被移除的片段将停止(而不是销毁)。如果用户返回以恢复片段,它会重新启动。如果您不将事务添加到后台堆栈,则片段在删除或替换时会被销毁。

此视图没有完全重绘,只是过度绘制,如果第二个片段没有背景或视图容器重绘,您将获得所描述的效果。这是我的理论:>。有时 Android 文档并不像我们希望的那样清晰。

于 2015-06-03T11:17:33.470 回答
1

问题是以下用例:

EventFragment从将“remove( EventFragment GameFragment).add(GameFragment)”事务推送到后台堆栈。如果我现在按下后退按钮,这笔交易将被撤消,一切都很好。后台再次为空,一切正常。但是,如果我不按返回按钮,而是通过菜单切换到另一个片段,则返回堆栈仍然有上述事务。现在按下返回将尝试撤消此事务...它只会在我的菜单单击处理程序中的代码从菜单中添加片段之前读取 EventFragment...这就是它可能发生的方式...

简单的解决方案,如果我只希望每个菜单条目都有一个 backstack 并且想要删除 backstack,如果我在菜单中选择我的应用程序的另一个区域,则在通过菜单转到另一个区域之前清除 backstack...

所以添加' fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);' 在替换当前片段之前将解决问题(我将此解决方案作为评论添加到我的主要帖子中)

于 2015-06-04T19:06:05.010 回答