現在動作しているアプリの動的機能モジュールでナビゲーション コンポーネントを使用しようとしています。最近、ようこそ画面とホーム画面の間のナビゲーションをロードするためのメイン ナビゲーション グラフを構成しました。
(メイン ナビゲーション グラフで定義されているように) ホーム画面をレンダリングすると、動的機能モジュールのフラグメントは次のようになります。動的にBottomNavigationView を使用してレイアウトにロードおよび表示されますが、含まれるナビゲーション グラフとして、含まれるナビゲーション グラフ内の宛先/アクションは実行されず、HomeFragment の NavController で認識されません。
私の質問は次のとおりです。インストール時にアプリに含まれるモジュールのナビゲーション フローを確保するために、動的機能モジュール ナビゲーション グラフをホーム画面に正常にロードするにはどうすればよいですか?
「含まれるモジュールのナビゲーション フローを確保する」と言うとき、含まれるナビゲーション グラフとその目的地は、単一のナビゲーション グラフを使用する場合と同様に、通常のナビゲーション セットアップと同じように機能する必要があるという事実を指しています。
たとえば、ホーム画面の下部ナビゲーションで Tab01 を選択すると、ニュース フィードに関する情報のリストが表示され、ニュース アイテムをクリックすると、ニュース コンテンツ フラグメント画面に移動します。
このシナリオでは、次のエラーが表示されます。
java.lang.IllegalArgumentException: navigation destination action_news_list_to_detail is unknown to this NavController
at androidx.navigation.NavController.navigate(NavController.java:919)
at androidx.navigation.NavController.navigate(NavController.java:859)
at androidx.navigation.NavController.navigate(NavController.java:845)
at androidx.navigation.NavController.navigate(NavController.java:1093)
at org.example.dfm01.Tab01Fragment.handleSelectedItem(Tab01Fragment.kt:72)
at org.example.dfm01.Tab01Fragment.access$handleSelectedDestination(Tab01Fragment.kt:23)
at org.example.dfm01.Tab01Fragment$setupRecyclerView$$inlined$apply$lambda$1.invoke(Tab01Fragment.kt:58)
at org.example.dfm01.Tab01Fragment$setupRecyclerView$$inlined$apply$lambda$1.invoke(Tab01Fragment.kt:23)
at org.example.dfm01.Tab01recyclerAdapter$ViewHolder$bind$$inlined$apply$lambda$1.onClick(Tab01recyclerAdapter.kt:97)
at android.view.View.performClick(View.java:7155)
at android.view.View.performClickInternal(View.java:7124)
at android.view.View.access$3500(View.java:808)
at android.view.View$PerformClick.run(View.java:27370)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:359)
at android.app.ActivityThread.main(ActivityThread.java:7418)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
ナビゲーションに次の依存関係を使用しています。
api "androidx.navigation:navigation-fragment-ktx:$nav_version"
api "androidx.navigation:navigation-ui-ktx:$nav_version"
api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
コードはホーム画面/フラグメントに注意します:
<include-dynamic... />
タグを使用して動的機能モジュールをロードする 2 つ目のナビゲーション グラフを追加しました。
[nav_graph_home.xml]
<?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">
<include-dynamic
android:id="@+id/included_nav_01"
app:graphPackage="org.example.dfm01"
app:graphResName="nav_tab_01"
app:moduleName="example_dfm_01" />
<include-dynamic
android:id="@+id/included_nav_02"
app:graphPackage="org.example.dfm02"
app:graphResName="nav_tab_02"
app:moduleName="example_dfm_02" />
<include-dynamic
android:id="@+id/included_nav_03"
app:graphPackage="org.example.dfm03"
app:graphResName="nav_tab_03"
app:moduleName="example_dfm_03" />
<include-dynamic
android:id="@+id/included_nav_04"
app:graphPackage="org.example.dfm04"
app:graphResName="nav_tab_04"
app:moduleName="example_dfm_04" />
</navigation>
- ホーム フラグメントのレイアウトで BottomNavigationView ウィジェットのメニュー xml ファイルを構成し、後でレイアウトに app:menu とグラフ参照を FragmentContainerView に追加しました。
[fragment_home.xml]
<?xml version="1.0" encoding="UTF-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment_home"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph_home" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_home"
app:menu="@menu/menu_home_bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
- HomeFragment クラス内で、2 番目のナビゲーション グラフを使用して、BottomNavigationView のナビゲーション フローをセットアップしました。
[ホームフラグメント.kt]
class HomeFragment : Fragment(fragment_home) {
private val viewBinding: FragmentHomeBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val innerNavHostFragment =
childFragmentManager.findFragmentById(R.id.nav_host_fragment_home) as NavHostFragment
val innerNavController = innerNavHostFragment.navController
viewBinding.apply {
NavigationUI.setupWithNavController(bottomNavHome, innerNavController)
}
}
}