当前位置: 首页 > 知识库问答 >
问题:

嵌套片段和后堆栈

端木夕
2023-03-14

Back Stack是否支持与Android中的嵌套片段交互?

如果是这样,我做错了什么?在我的实现中,后退按钮完全忽略了我将此事务添加到后堆栈的事实。我希望这不是因为嵌套片段的问题,只是我做了一些不正确的事情。

以下代码位于我的一个片段中,用于将新片段与当前显示的任何嵌套片段交换:

     MyFragment fragment = new MyFragment();
     FragmentTransaction ft = getChildFragmentManager().beginTransaction();
     ft.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_left, R.animator.slide_in_from_left, R.animator.slide_out_right);
     ft.addToBackStack(null);
     ft.replace(R.id.myFragmentHolder, fragment);
     ft.commit();

共有3个答案

施阎宝
2023-03-14

从API 26开始,FragmentTransaction中有一个setPrimaryNavigation片段方法,可用于

在此FragmentManager中设置当前活动的片段作为主导航片段。

这意味着

将首先调用主导航片段的子FragmentManager来处理委派的导航操作,例如FragmentManager。popBackStack(),如果没有向pop-to提供ID或事务名称。片段系统之外的导航操作可以选择将这些操作委托给FragmentManager返回的主导航片段。getPrimaryNavigationFragment()。

正如@la_urre在接受的答案中所提到的,正如您在FragmentActivity的源代码中所看到的那样,FragmentActivity'son backpressed将调用其FragmentManager'sPopbackimmediate(),这反过来将检查是否存在mPrimaryNav(我假设是主导航)片段,获取其子片段管理器并弹出其Backback。

易焱
2023-03-14

在我当前的项目中,我们有多个“嵌套层”,因此我想出了以下解决方法,仅针对顶级片段管理器自动弹出背包:

@Override
public void onBackPressed() {
    SparseArray<FragmentManager> managers = new SparseArray<>();
    traverseManagers(getSupportFragmentManager(), managers, 0);
    if (managers.size() > 0) {
        managers.valueAt(managers.size() - 1).popBackStackImmediate();
    } else {
        super.onBackPressed();
    }
}

private void traverseManagers(FragmentManager manager, SparseArray<FragmentManager> managers, int intent) {
    if (manager.getBackStackEntryCount() > 0) {
        managers.put(intent, manager);
    }
    if (manager.getFragments() == null) {
        return;
    }
    for (Fragment fragment : manager.getFragments()) {
        if (fragment != null) traverseManagers(fragment.getChildFragmentManager(), managers, intent + 1);
    }
}
东方辉
2023-03-14

我有同样的问题,我想嵌套片段,并为每个嵌套片段保留一个后堆栈。

但是...似乎这种情况不是v4支持库处理的。在库中的Fragmentactive代码中,我可以找到:

public void onBackPressed() {
    if (!mFragments.popBackStackImmediate()) {
        finish();
    }
}

mFragments表示活动的FragmentManager,但该管理器似乎并未将弹出窗口“传播”给子管理器。一种解决方法是在子管理器上手动调用popBackStackImtify(),就像从Fragmentactive继承的活动中一样:

private Fragment myFragmentContainer;

    @Override
    public void onBackPressed() {
            if (!myFragmentContainer.getChildFragmentManager().popBackStackImmediate()) {
                finish(); //or call the popBackStack on the container if necessary
            }
    }

也许有一种更好的方法,一种更自动化的方法,但对于我的需求来说,这是可以的。

 类似资料:
  • 根据谷歌的文档: 现在可以在片段中嵌入片段。这对于各种情况都很有用,在这些情况下,您需要将动态和可重用的UI组件放置到本身是动态和可重用的UI组件中。例如,如果使用ViewPager创建左右滑动并占用大部分屏幕空间的片段,现在可以将片段插入每个片段页面。要嵌套片段,只需对要添加片段的片段调用getChildFragmentManager()。这将返回一个FragmentManager,您可以像通常

  • 对于我工作的应用程序,我需要实现可访问性。除了一个屏幕外,其他一切都很好,我必须将片段添加到我的活动中。基本上,上面的片段是一个拨号键盘,用于输入密码。此片段与fragmentTransaction一起添加。 问题是对讲的焦点是设置在下面片段的元素上。 您知道是否有办法将对讲焦点设置在拨号片段上吗?我只想“禁用”下面的片段以获得焦点 谢谢,

  • 你好,堆栈溢出的好程序员!我已经花了一个星期的时间来解决这个问题,现在非常渴望一个解决方案。 我正在使用android。应用程序。不要将片段与支持片段混淆。 我有6个子片段名为: <代码>片段一 碎片二 碎片三 碎片a 碎片b 显示子片段<代码>片段A、<代码>片段B和<代码>片段C。 我正在尝试转换/设置父片段和子片段的动画。子片段平稳过渡,如预期。然而,当我转换到一个新的父片段时,它看起来很糟

  • 我有一个ViewPagerContainer片段,在应用程序启动时加载。ViewPagerContainer片段将两个选项卡(选项卡A和选项卡B)添加到操作栏。选项卡B有两个项目的列表视图。 我所做的:我在选项卡B片段中的列表视图项上附加了一个click listener,这样当用户单击一个项时,它会在第一个片段(即选项卡B下)内打开另一个片段(子片段)。 我陷入困境的地方:当用户按下后退按钮时,

  • 在我的应用程序中,一个

  • 可以使用保存删除片段时的状态,然后在将片段弹出后堆栈时恢复状态吗?当我从后堆栈还原片段时,savedInstanceState包始终为空。 现在,应用程序流程是:创建的片段->删除的片段(添加到后堆栈)->从后堆栈恢复的片段(savedInstanceState包为空)。 下面是相关代码: 我认为问题是在被移除和添加到后堆栈时从未被调用。如果我不能使用onsavedInstanceState(),