在 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) }
我创建了一个带有底部导航栏的应用程序,并使用 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) }