Création de la barre de navigation inférieure sur Kotlin avec Anko

En commençant un nouveau projet, j'ai décidé d'essayer d'abandonner complètement les fichiers XML, sur la base desquels les mises en page sont formées, et de créer des écrans à l'aide de la bibliothèque Anko. Ayant une petite expérience de développement pour Android (environ 2 ans) et encore moins d'expérience dans l'écriture de code sur Kotlin (un peu plus de six mois), j'ai immédiatement rencontré le problème de l'inclusion de la barre de navigation inférieure créée par BottomNavigationView dans l' application du composant d'architecture de navigation.


Tout d'abord, je me suis tourné vers Internet pour trouver une solution possible. Mais tous les articles que j'ai trouvés avec plus ou moins de clarté expliquaient comment travailler avec les composants de navigation et aucun (de ceux dont j'ai étudié les articles) ne le faisait sur Anko. Après avoir résolu la tâche, j'offre à la communauté mon option pour créer une barre de navigation inférieure.


Tout le code peut être consulté ici.
Je saute l'étape de création d'un nouveau projet dans Android Studio, je note simplement les dépendances suivantes pour travailler avec Anko et le composant d'architecture de navigation dans build.gradle au niveau du module:


implementation "org.jetbrains.anko:anko:$anko_version" implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version" implementation "com.android.support.constraint:constraint-layout:2.0.0-alpha3" implementation 'android.arch.navigation:navigation-fragment:1.0.0-beta02' implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-beta02' implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-beta02' implementation 'com.google.android.material:material:1.0.0' 

L'étape suivante consiste à créer la structure de la future application. Pour dessiner l'activité principale, au lieu du fichier xml, créez la classe MainActivityUI héritée de l'interface AnkoComponent:


 class MainActivityUI: AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { constraintLayout { } } } 

Dans la classe MainActivity, setContentView (R.layout.activity_main) est remplacé par MainActivityUI (). SetContentView (this).


Ensuite, nous créons des fragments de package dans lesquels nos fragments et notre package ui se trouveront pour placer les classes responsables du rendu des écrans des fragments correspondants. Voici la structure du projet:


 fragments ui HomeUI UsersUI DetailsUI MoreUI HomeFragment UsersFragment DetailsFragment MoreFragment 

Nous allons maintenant traiter directement de la navigation et de la création de la barre de navigation inférieure.
Une description détaillée de l'inclusion de nouveaux composants de navigation et une description du travail dans l'éditeur de navigation sont disponibles sur la page de documentation ici . Pour créer un fichier (graphique) pour la navigation entre les écrans d'application, vous devez ajouter un autre dossier au dossier res, à savoir la navigation, et y ajouter déjà le fichier navigation_graph.xml. Pour ce projet, ce sera comme ça:


 <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_graph" app:startDestination="@id/homeFragment"> <fragment android:id="@+id/homeFragment" android:name="com.arsinde.ankobottomnavbar.fragments.HomeFragment" android:label="HomeFragment"> <action android:id="@+id/action_homeFragment_to_detailsFragment" app:destination="@id/detailsFragment"/> </fragment> <fragment android:id="@+id/detailsFragment" android:name="com.arsinde.ankobottomnavbar.fragments.DetailsFragment" android:label="DetailsFragment"> <action android:id="@+id/action_detailsFragment_to_usersFragment" app:destination="@id/usersFragment"/> </fragment> <fragment android:id="@+id/usersFragment" android:name="com.arsinde.ankobottomnavbar.fragments.UsersFragment" android:label="UsersFragment"> <action android:id="@+id/action_usersFragment_to_moreFragment" app:destination="@id/moreFragment"/> </fragment> <fragment android:id="@+id/moreFragment" android:name="com.arsinde.ankobottomnavbar.fragments.MoreFragment" android:label="MoreFragment"/> </navigation> 

Pour afficher la barre elle-même, vous devez créer un autre dossier de ressources, à savoir le menu. Il contient le fichier responsable de la partie visible de la barre. Voici à quoi cela ressemble dans ce projet:


 <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@id/homeFragment" android:icon="@drawable/ic_home" android:title="@string/menu_title_home"/> <item android:id="@id/usersFragment" android:icon="@drawable/ic_users" android:title="@string/menu_title_users"/> <item android:id="@id/detailsFragment" android:icon="@drawable/ic_info" android:title="@string/menu_title_details"/> <item android:id="@id/moreFragment" android:icon="@drawable/ic_more" android:title="@string/menu_title_more"/> </menu> 

Il est temps de tout assembler et de voir comment cela fonctionne.


Ajoutez un conteneur pour les fragments dans MainActivityUI et définissez également un conteneur pour la barre de navigation.


 constraintLayout { val fragmentContainer = frameLayout { id = R.id.fragment_container }.lparams { width = matchParent height = matchConstraint } val bottomNavigation = bottomNavigation { id = R.id.bottom_nav_view inflateMenu(R.menu.bottom_navigation_menu) } applyConstraintSet { fragmentContainer { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to TOP of PARENT_ID, BOTTOM to TOP of R.id.bottom_nav_view ) } bottomNavigation { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to BOTTOM of R.id.fragment_container, BOTTOM to BOTTOM of PARENT_ID ) } } } 

Il convient de noter spécialement que bottomNavigation dans cet exemple est une fonction d'extantion, qui a la forme suivante:


 inline fun ViewManager.bottomNavigation(init: BottomNavigationView.() -> Unit = {}) = ankoView({ BottomNavigationView(it) }, theme = 0, init = init) 

Maintenant, dans MainActivity, vous devez définir l'objet NavHostFragment (voir le dock):


 private val host by lazy { NavHostFragment.create(R.navigation.navigation_graph) } 

Et dans la méthode onCreate (), définissez:


 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, host) .setPrimaryNavigationFragment(host) .commit() 

La touche finale - ajoutez à onStart () MainActivity un objet de la classe NavController, qui vous permet de faire la transition entre les fragments en choisissant l'un ou l'autre objet de la barre de navigation:


 override fun onStart() { super.onStart() val navController = host.findNavController() findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.setupWithNavController(navController) navController.addOnDestinationChangedListener{_, destination, _ -> val dest: String = try { resources.getResourceName(destination.id) } catch (e: Resources.NotFoundException) { Integer.toString(destination.id) } Log.d("NavigationActivity", "Navigated to $dest") } } 

Lancez l'application et vois là ...


Capture d'écran

Source: https://habr.com/ru/post/fr441618/


All Articles