Vous êtes maintenant dans la quatrième partie d'un excellent article sur le composant de navigation dans un projet multi-module. Si vous savez déjà:
Qu'est-ce que le composant de navigation
Comment fonctionne le plugin Safe Args et ce qu'il fait
Comment pouvez-vous créer un travail avec le composant de navigation dans un projet multi-module
Alors bienvenue dans la dernière partie de l'histoire sur mon expérience avec cette merveilleuse bibliothèque - sur la solution pour la navigation multipiste de type iOS.
Vous pouvez voir comment tout cela fonctionne ici
Si vous ne le savez pas, sortez et entrez normalement, lisez d'abord les trois articles ci-dessus.
En plus de la bibliothèque de composants de navigation, Google a publié plusieurs modules complémentaires appelés NavigationUI qui vous aident à connecter la navigation à BottomBar, Menu et d'autres composants standard. Mais souvent, il est nécessaire que chaque onglet ait sa propre pile et que les états actuels soient enregistrés lors du basculement entre eux. Malheureusement, hors de la boîte, le composant de navigation et NavigationUI ne le font pas.
La prise en charge de cette approche a été fournie par Google lui-même dans son référentiel d'architecture-components-samples sur GitHub ( https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample ). Son essence est simple:
Ajoutez FragmentContainer.
NavHostFragment .
NavHostFragment FragmentManager-a.
, :
. NavigationBottomBar Deep Link-. , deep link- . , — . NavigationExtensions 250 loc, lazy- NavHost-, :
/ NavHost-:
fun obtainNavHostFragment(
fragmentManager: FragmentManager,
fragmentTag: String,
navGraphId: Int,
containerId: Int
): NavHostFragment {
// If the Nav Host fragment exists, return it
val existingFragment =
fragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment?
existingFragment?.let { return it }
// Otherwise, create it and return it.
val navHostFragment = NavHostFragment.create(navGraphId)
fragmentManager.beginTransaction()
.add(containerId, navHostFragment, fragmentTag)
.commitNow()
return navHostFragment
}
NavHost-:
protected fun selectTab(tab: Tab) {
val newFragment = obtainNavHostFragment(
childFragmentManager,
getFragmentTag(tabs.indexOf(tab)),
tab.graphId,
containerId
)
val fTrans = childFragmentManager.beginTransaction()
with(fTrans) {
if (selectedFragment != null) detach(selectedFragment!!)
attach(newFragment)
commitNow()
}
selectedFragment = newFragment
currentNavController = selectedFragment!!.navController
tabSelected(tab)
}
“Back”:
activity?.onBackPressedDispatcher?.addCallback(
viewLifecycleOwner,
object: OnBackPressedCallback(true){
override fun handleOnBackPressed() {
val isNavigatedUp = currentNavController.navigateUp()
if(isNavigatedUp){
return
}else{
activity?.finish()
}
}
}
)
iOS-like , lazy- . — , .