web-dev-qa-db-ja.com

ネストされたナビゲーショングラフを備えたArchの新しいナビゲーションコンポーネント

1つのケースがあり、Archナビゲーションコンポーネントで実装したいと考えています。たとえば、2つのナビゲーショングラフ(メインとネスト)があります。ネストからメイングラフを呼び出すことができますか?

21

重要なのは、正しいグラフでナビゲートするために正しいNavControllerを取得することです。このシナリオを例に取りましょう:

_MainActivity
|- MainNavHost
   |- NavBarFragment
   |  |- NestedNavHost
   |  |  |-NestedContentFragment1
   |  |  |-NestedContentFragment2
   |  |
   |  |- BottomNavigationView
   |
   |- LoginFragment
_

メイングラフとネストされたグラフは別々のxmlファイルにあります。ナビゲーションが異なるレイアウトエリアを対象としているため、これは2つの異なるNavHostsを必要とするため、これが必要です。各Navhostはidでグラフを参照する必要があります。これには、異なるリソースファイルにあることが必要です。

ポイントは、特定のグラフ内を移動するには、適切なグラフの所有者への参照を取得する必要があるということです。これを行うには、Navigation.findNavController(view)を呼び出すときにview引数が重要です。

文書によると

NavHostFragmentsは、ナビゲーションヘルパークラスのメソッドを通じて子孫がコントローラーインスタンスを取得できるように、ビューサブツリーのルートにナビゲーションコントローラーを登録します。

たとえば、NavBarFragmentの中に

_override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    navController = Navigation.findNavController(view)
}
_

ここでviewNestedNavHostの-​​(ネストされたNavHostFragment)であり、子孫ではありません。つまり、findNavControllerツリーの上流を検索し、MainNavHostNavControllerを返します。

代わりに書く場合

_override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val fragmentContainer = view.findViewById<View>(R.id.nestedNavHostFragment)
    navController = Navigation.findNavController(fragmentContainer)
}
_

ここで、nestedNavHostFragmentはレイアウトのfragmentタグ内のIDです。正しいNestedNavHostへの参照を取得します。これは、ビューがfindNavControllerに渡すためです。 NestedNavHostのサブツリーに属します。

同様に、NavControllerの中からメインNestedContentFragmentへの参照を取得する必要がある場合、次のようにします。

_override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    // we can get the innermost NavController using this view,
    // because we are inside its subtree:
    nestedNavController = Navigation.findNavController(view)

    // we can find the outer NavController passing the owning Activity
    // and the id of a view associated to that NavController,
    // for example the NavHostFragment id:
    mainNavController = Navigation.findNavController(activity!!, R.id.mainNavHostFragment)
}
_
33
devrocca

実際に動作しています

val Host: NavHostFragment? = (childFragmentManager.findFragmentById(R.id.main_app_fragment_container)  as NavHostFragment?)

メインフラグメントからナビゲートできます

2
cosinus

同じ問題。Webで見つかったすべての例は、基本的なセットアップを繰り返します。ログインがメインフラグメントに移動した後、ログインフラグメントで始まるメインアクティビティにナビゲーショングラフがあり、下部ナビゲーションビューの別のナビゲーショングラフがあります。問題は、メインフラグメントがメインアクティビティナビゲーショングラフに関連付けられていることです。メインフラグメント内のフラグメントのみがメインフラグメントナビグラフを使用できると思います。

0
cosinus

実際には、 グローバルアクション を使用して、ネストされたナビゲーショングラフの宛先からメインナビゲーショングラフの宛先に移動できます。

ネストされたナビゲーショングラフからメインナビゲーショングラフの目的の宛先へのグローバルアクションを作成します(下の画像で強調表示されています)

例:

nav graph

<navigation Android:id="@+id/main_nav_graph"
     ... >
     <fragment Android:id="@+id/fragStart" .../>
     <fragment .../>
     <fragment .../>

     <navigation  Android:id="@+id/nested_nav_graph">
           ...

     <!-- Global Action -->
     <action
         Android:id="@+id/action_global_start"
         app:destination="@id/fragStart" />
     </navigation>

</navigation>

メイングラフの目的地に移動するには

findNavController().navigate(R.id.action_global_start)
0
user158