web-dev-qa-db-fra.com

Nouveau composant de navigation d'Arch avec graphique de navigation imbriqué

J'ai un cas et je souhaite le mettre en œuvre par le composant de navigation Arch. Par exemple, j'ai 2 graphiques de navigation (principal et imbriqué). Puis-je appeler le graphe principal depuis imbriqué et comment? exemple

21
Serhii Pylypchuk

Le but est d'obtenir le bon NavController pour naviguer dans le bon graphique. Prenons ce scénario comme exemple:

MainActivity
|- MainNavHost
   |- NavBarFragment
   |  |- NestedNavHost
   |  |  |-NestedContentFragment1
   |  |  |-NestedContentFragment2
   |  |
   |  |- BottomNavigationView
   |
   |- LoginFragment

Le graphique principal et le graphique imbriqué se trouvent dans des fichiers xml distincts: cela est nécessaire, pour autant que je sache, car les navigations ciblent différentes zones de mise en page, elles nécessitent donc deux NavHosts différents. Chaque Navhost devra référencer son graphe par id, ce qui les obligera à se trouver dans différents fichiers de ressources.

Le fait est que pour naviguer dans un graphe spécifique, nous devons obtenir une référence au propriétaire du bon graphe: pour ce faire, lors de l'appel de Navigation.findNavController(view), l'argument view est crucial.

Les documents disent que

NavHostFragments enregistre leur contrôleur de navigation à la racine de leur sous-arborescence de vue de sorte que tout descendant puisse obtenir l'instance de contrôleur via les méthodes de la classe d'aide à la navigation

Ainsi, par exemple, si à l'intérieur de NavBarFragment nous écrivons

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

ici view est un parent du NestedNavHost (c'est-à-dire le NavHostFragment imbriqué), pas un descendant, ce qui signifie que findNavController recherchera en amont dans l'arborescence et renverra le MainNavHostNavController.

Si à la place nous écrivons

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

nestedNavHostFragment est l'ID dans la balise fragment dans la mise en page, nous obtenons une référence à la bonne NestedNavHost, car la vue que nous passons maintenant à findNavController appartient à la sous-arborescence de NestedNavHost.

De même, si vous devez obtenir une référence au NavController principal à l'intérieur d'un NestedContentFragment, voici ce que nous pouvons faire:

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

Fonctionne réellement, en utilisant

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

Je peux naviguer à partir du fragment principal

2
cosinus

Même problème, tous les exemples trouvés sur le Web parcourent la configuration de base. J'ai un graphique de navigation dans l'activité principale qui commence par le fragment de connexion, après la connexion au fragment principal, qui a un autre graphique de navigation avec une vue de navigation inférieure. Le problème est que le fragment principal est lié au graphique de navigation de l'activité principale. Je pense que seuls les fragments à l'intérieur du fragment principal peuvent utiliser le graphique de navigation du fragment principal.

0
cosinus

En fait, vous pouvez utiliser Actions globales pour naviguer d'une destination de graphique de navigation imbriquée à une destination de graphique de navigation principale.

Créez une action globale à partir du graphique de navigation imbriqué vers la destination souhaitée dans le graphique de navigation principal (mis en évidence dans l'image ci-dessous)

exemple:

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>

Pour naviguer vers la destination principale du graphique, utilisez

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