Android BackStack NavigationDrawer

Android BackStack NavigationDrawer

过去几天我一直在处理一个问题,但似乎没有找到答案。

描述:我有一个包含导航抽屉的主 activity。导航抽屉的每个项目(单击时)都会创建一个片段。在该片段中,有一个对象的 listView,单击它会创建其他片段。在那些片段中,我有另一个对象列表视图,它打开其他片段。换句话说,有一系列片段可以打开其他片段。像这样:

http://s22.postimg.org/pddo5gsv5/backstack.png

为了能够返回到每个片段,我实现了 addToBackstack("string") 方法。

我的问题是,我如何为我的应用程序实现正确的后台堆栈,以便当我单击导航抽屉项目时,所有已添加到后台堆栈的片段都被清除,而不是导航抽屉项目打开的片段。

如有任何帮助,我们将不胜感激。谢谢!

编辑

好的,看来我想通了。考虑到我从回复中得到的建议,这是我想出的解决方案:

@Override
public void onBackPressed() {
    int count = getFragmentManager().getBackStackEntryCount();
    if (count != 0) {
        FragmentManager.BackStackEntry backEntry = getFragmentManager()
                .getBackStackEntryAt(
                        getFragmentManager().getBackStackEntryCount() - 1);
        if (backEntry.getName() == NAVIGATION) {
            finish();
        } else
            getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

换句话说:首先,我为顶级片段添加了一个后台堆栈条目,给它们一个特定的标签。我已经覆盖了 Activity 的后退按钮功能,以便当最后一个 backstack 条目是完成 activity 的顶级片段时(这样它就不会简单地从 [=41= 中分离片段],住它空)。否则,如果最后一个条目不是顶级片段,则执行 popBackStack。 PS:所有非顶级片段都被添加到带有与顶级标签不同的标签的后台堆栈中。此外,我必须在导航抽屉的点击侦听器中执行 POP_BACK_STACK_INCLUSIVE。

getFragmentManager().popBackStack(null,
                FragmentManager.POP_BACK_STACK_INCLUSIVE);

感谢大家的建议,希望此编辑对其他用户有所帮助。

您可以使用类似以下内容的方式清除片段后台堆栈:

fragmentManager.popBackStack("string", FragmentManager.POP_BACK_STACK_INCLUSIVE);

然后您可以像往常一样 addToBackstackcommitMore info.

显示我通常在导航抽屉中使用它的方式的代码片段:

FragmentManager fragmentManager = getSupportFragmentManager();
if(clearBackStack) {
    fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
if(!clearBackStack) {
    ft.addToBackStack(null);
}
ft.commit();

您可以使用以下代码解决您的问题:

getFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, fragment)
                    .addToBackStack(fragment_tag)
                    .commit();

为了使上面的代码工作,您必须动态创建片段。由于 无法替换硬编码片段 。为此,您可以创建一个容器(FrameLayout 等),在我们的示例中它的 ID 为 fragment_container。然后,上面的代码将在容器中动态添加片段。最后,您必须将 fragment_tag 作为参数传递给 addToBackStack 方法。这意味着,该交易将被添加到后台堆栈中。最后,为了从后台获取它,你必须使用下面的代码:

getFragmentManager().popBackStack(fragment_tag, FragmentManager.POP_BACK_STACK_INCLUSIVE));

POP_BACK_STACK_INCLUSIVE标志,确保"all matching entries will be consumed until one that doesn't match is found or the bottom of the stack is reached. Otherwise, all entries up to but not including that entry will be removed."