Pour une nouvelle application, j'utilise la bibliothèque de navigation Jetpack pour implémenter une navigation arrière appropriée. Le premier niveau de navigation est un tiroir de navigation qui fonctionne très bien avec la navigation Jetpack comme décrit dans la documentation. Mais il existe un autre niveau de navigation implémenté avec ViewPager et TabLayout. Les fragments commutés par TabLayout contiennent une hiérarchie de navigation linéaire supplémentaire. Cependant, il ne semble pas y avoir de prise en charge de ViewPager/TabLayout dans la navigation Jetpack. Un FragmentPagerAdapter doit être implémenté et la pile arrière gérée se termine lors du changement d'onglets. Il existe un décalage entre la navigation de niveau supérieur et la navigation à l'intérieur de chaque onglet. Existe-t-il un moyen de faire fonctionner cela avec Jetpack Navigation?
Expérimenté avec différentes approches pour gérer TabLayout
avec Navigation Jetpack . Mais rencontrez des problèmes comme avoir un historique complet de basculer entre les onglets plusieurs fois, etc.
Naviguer sur Google connu Android Problèmes avant de lancer une demande de démonstration, j'ai trouvé cela problème existant .
Son état est Fermé marqué comme Comportement prévu avec l'explication suivante:
La navigation se concentre sur les éléments qui affectent la pile arrière et les onglets n'affectent pas la pile arrière - vous devez continuer à gérer les onglets avec
ViewPager
etTabLayout
- En vous référant à formation Youtube =.
Ce qui a fonctionné jusqu'à présent:
Dans navigation_graph.xml
dans le graphe imbriqué:
Je n'avais pas besoin de changer le ViewPager, et des directions ont été créées pour les fragments d'enfant afin que la navigation soit possible à partir de là.
Oui , mais vous devrez implémenter votre propre destination personnalisée, en implémentant la classe Navigator
et en remplaçant au moins les méthodes popBackStack()
et navigate()
.
Dans votre navigate
, vous devrez appeler la ViewPager.setCurrentTab()
et l'ajouter à votre back stack. Quelque chose comme:
lateinit var viewPager: ViewPager? = null // you have to provide this in the constructor
private val backstack: Deque<Pair<Int, View>> = ArrayDeque
override fun navigate(destination: Destination, args: Bundle?,
navOptions: NavOptions?, navigatorExtras: Extras?
): NavDestination? {
viewPager.currentItem = destination.id
backstack.remove(destination.id) // remove so the stack has never two of the same
backstack.addLast(destination.id)
return destination
}
Dans votre popBackStack
, vous devrez reculer le dernier élément sélectionné. Quelque chose comme:
override fun popBackStack(): Boolean {
if(backstack.size() <= 1) return false
viewPager.currentItem = backstack.peekLast()
backstack.removeLast()
return true
}
Vous pouvez trouver une brève explication sur documents Android et cet exemple du navigateur personnalisé pour FragmentDialog
.
Après avoir implémenté votre ViewPagerNavigator
, vous devrez l'ajouter à votre NavController
et définir les écouteurs de la sélection des vues d'onglets pour appeler NavController.navigate()
.
J'espère que quelqu'un implémentera une bibliothèque pour tous ces modèles courants (ViewPager, ViewGroup, FragmentDialog), si quelqu'un le trouve, mettez-le dans les commentaires.