Composant de navigation et navigation multi backstack

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à:





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:









  1. Ajoutez FragmentContainer.





  2. NavHostFragment .





  3. NavHostFragment FragmentManager-a.





, :





  • sign in / up flow, on boarding , , . , , .





  • . 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- .  —  , .








All Articles