在 Jetpack 导航中使用具有多个图形的全局操作

Using global actions with multiple graphs in jetpack navigation

我创建了一个带有底部导航栏的应用程序,并使用 google 的高级导航示例添加了四个不同的导航图

之后,我添加了第五个名为设置的图表,其中包含设置片段和全局操作

我在前四张图的每张图上都添加了包含到该图

当我执行 findNavController(R.id.container).navigate(SettingsDirections.showSettings()) 之类的操作时,应用程序崩溃,因为它找不到目的地或操作

但是当我在每个图表中复制 fragment 和全局 action 并调用上面的代码(使用该图表的方向)时,它起作用了

我错过了什么吗?不包括实际复制其他图表中的所有内容吗?

include 标签似乎并没有真正包含所有导航图,包括全局操作

如果有人想做类似的事情,我就是这样做的

首先我更新了设置导航以包含一个虚拟操作来显示设置,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/settings"
    app:startDestination="@+id/settings_dest">

    <include app:graph="@navigation/questions" />

    <!--this is just so safeargs will create a SettingsNavigation.showSettings it is never actually used-->
    <action
        android:id="@+id/show_settings"
        app:destination="@id/settings_dest" />

    <fragment
        android:id="@+id/settings_dest"
        android:name="com.example.app.ui.fragments.SettingsFragment"
        android:label="@string/settings"
        tools:layout="@layout/fragment_settings" >

        <argument
            app:argType="com.example.app.ui.model.SettingsProfile"
            android:name="profile"
            app:nullable="false"/>
    </fragment>
</navigation>

然后在每个我想使用 show_settings 操作的导航图上,我会通过包含以下内容来执行:

<include app:graph="@navigation/settings" />

<action
    android:id="@+id/show_settings"
    app:destination="@id/settings"
    app:enterAnim="@anim/fade_in"
    app:exitAnim="@anim/fade_out"
    app:popEnterAnim="@anim/fade_in"
    app:popExitAnim="@anim/fade_out" />

所以现在当我想使用方向转到设置时,我会这样做

findNavController().navigate(SettingsDirections.showSettings(profile))

这将使用在我的 settings.xml 中创建的指示来执行我当前导航控制器中的操作

重要的是,包含文件中的操作 ID 和包含它的文件的操作 ID 相同

我在设置默认动画的时候创建了一个扩展函数

fun View.navigate(id: Int, navOptions: NavOptions? = null){
  var updatedNavOptions = navOptions

  if(updatedNavOptions == null){
    updatedNavOptions = navOptions {
        anim {
            enter = R.anim.slide_in_right
            exit = R.anim.slide_out_left
            popEnter = R.anim.slide_in_left
            popExit = R.anim.slide_out_right
        }
    }
}

    this.findNavController().navigate(id, null, updatedNavOptions)
}

在我的片段中这样做:

my_view.click { view?.navigate(R.id.how_referral_program_works) }