BottomSheetDialogFragment中的NavigationComponent导航

13
Android的Navigation组件能否用于在BottomSheet内导航(即在单个底部页替换/添加片段)?
我知道如何使用导航图中的标记启动BottomSheetDialogFragment。例如,下面的nav_graph.xml允许用户从一个BottomSheetDialogFragment(fragmentOne)导航到另一个BottomSheetDialogFragment(fragmentTwo)。FragmentTwo作为第二个BottomSheet打开在FragmentOne的BottomSheet上方。
但是,如果我想要fragmentTwo在相同的BottomSheet中替换fragmentOne,我应该怎么做呢?如何使用导航图实现这一点?
<navigation android:id="@+id/nav_graph"
        app:startDestination="@id/fragmentOne">

    <dialog android:id="@+id/fragmentOne"
        android:name="com.example.navcomponentapp.FragmentOne"
        android:label="fragment_fragment_one"
        tools:layout="@layout/fragment_fragment_one">

        <action android:id="@+id/action_fragmentOne_to_fragmentTwo2"
            app:destination="@id/fragmentTwo"/>
    </dialog>

    <dialog android:id="@+id/fragmentTwo"
        android:name="com.example.navcomponentapp.FragmentTwo"
        android:label="fragment_fragment_two"
        tools:layout="@layout/fragment_fragment_two"/>
</navigation>

演示(这不是我想要的。我不想让一个BottomSheet在另一个BottomSheet上打开)


3
我还必须对回到工作中做这件事情。 dialog.setOnKeyListener { arg0, keyCode, event -> if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) { 如果不是通过导航控制器返回,就关闭对话框并返回true。 dialog.dismiss() true } 返回true } - uberchilly
1个回答

9
NavHostFragment 是一个容器,它的内容会被替换。所以,如果您想在 BottomSheetDialogFragment 中拥有一个与外部 NavHostFragment 的容器(即整个活动的整体内容)不同的容器,您需要在您的 BottomSheetDialogFragment 布局中添加一个单独的 NavHostFragment,并且该容器具有自己的导航图。
然后,在较小的容器内进行导航将仅替换底部表单中的内容(如果您想要在外部级别执行 navigate() 操作,则可以使用 requireParentFragment().findNavController() 访问外部 NavController)。

1
谢谢!我能够按照你的建议使它工作了。第一次启动BottomSheet时,它可以正常工作。但是当我尝试第二次启动BottomSheet时,我会得到Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f080095, tag null, or parent id 0xffffffff with another fragment for androidx.navigation.fragment.NavHostFragment at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:116)的错误提示。 - VIN
我通过MainActivity上的按钮启动BottomSheet。btn_bottom_sheet.setOnClickListener { FragmentOne().show(supportFragmentManager, "appBottomSheet") } - VIN
你手动调用 show() 来显示你的 BottomSheetDialogFragment,而不是使用 <dialog> 目标来显示你的对话框,这有什么原因吗?确保你没有在多个地方使用相同的 android:id(你的外部 NavHostFragment 不应该与内部的相同)。 - ianhanniballake
我使用show()的原因是我正在尝试使用导航组件,从底部表单作为导航宿主开始,而无需将活动作为起始导航宿主。你知道这是否可能吗? - VIN
1
@ianhanniballake,有没有办法通过URI深度链接到底部表中此内部导航宿主的目标?类似的用例是当我们在一个片段中有底部导航时。这也需要额外的导航宿主。 - uberchilly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接