Als ich ein neues Projekt startete, beschloss ich, die XML-Dateien, auf deren Grundlage Layouts erstellt werden, vollständig aufzugeben und mithilfe der Anko-Bibliothek Bildschirme zu erstellen. Mit ein wenig Entwicklungserfahrung für Android (ca. 2 Jahre) und noch weniger Erfahrung beim Schreiben von Code auf Kotlin (etwas mehr als sechs Monate) stieß ich sofort auf das Problem, die Navigationsarchitekturkomponente in die Anwendung aufzunehmen oder vielmehr die von BottomNavigationView erstellte untere Navigationsleiste zu rendern .
Zunächst habe ich mich an das Internet gewandt, um eine mögliche Lösung zu finden. Aber alle Artikel, die ich mit unterschiedlicher Klarheit gefunden habe, erzählten, wie man mit Navigationskomponenten arbeitet, und keiner (von denen, deren Artikel ich studiert habe) hat es auf Anko getan. Nachdem ich die Aufgabe gelöst habe, biete ich der Community die Möglichkeit, eine untere Navigationsleiste zu erstellen.
Der gesamte Code kann hier eingesehen werden.
Ich überspringe die Phase des Erstellens eines neuen Projekts in Android Studio. Ich beachte nur die folgenden Abhängigkeiten für die Arbeit mit Anko und der Navigationsarchitekturkomponente in build.gradle auf Modulebene:
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'
Der nächste Schritt besteht darin, die Struktur der zukünftigen Anwendung zu erstellen. Um die Hauptaktivität anstelle der XML-Datei zu zeichnen, erstellen Sie die MainActivityUI-Klasse, die von der AnkoComponent-Schnittstelle geerbt wurde:
class MainActivityUI: AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { constraintLayout { } } }
In der MainActivity-Klasse wird setContentView (R.layout.activity_main) durch MainActivityUI () ersetzt. SetContentView (this).
Dann erstellen wir Paketfragmente, in denen unsere Fragmente und die Paket-Benutzeroberfläche liegen, um die Klassen zu platzieren, die für das Rendern von Bildschirmen der entsprechenden Fragmente verantwortlich sind. Dies ist die Struktur des Projekts:
fragments ui HomeUI UsersUI DetailsUI MoreUI HomeFragment UsersFragment DetailsFragment MoreFragment
Jetzt beschäftigen wir uns direkt mit der Navigation und der Erstellung der unteren Navigationsleiste.
Eine ausführliche Beschreibung der Aufnahme neuer Navigationskomponenten und eine Beschreibung der Arbeit im Navigationseditor finden Sie auf der Dokumentationsseite hier . Um eine Datei (Grafik) für die Navigation zwischen Anwendungsbildschirmen zu erstellen, müssen Sie dem res-Ordner einen weiteren Ordner hinzufügen, nämlich die Navigation, und ihm bereits die Datei navigation_graph.xml hinzufügen. Für dieses Projekt wird es so sein:
<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>
Um die Leiste selbst anzuzeigen, müssen Sie einen anderen Ressourcenordner erstellen, nämlich das Menü. Es enthält die Datei, die für den sichtbaren Teil der Leiste verantwortlich ist. So sieht es in diesem Projekt aus:
<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>
Es ist Zeit, alles zusammenzusetzen und zu sehen, wie es funktioniert.
Fügen Sie in MainActivityUI einen Container für Fragmente hinzu und definieren Sie einen Container für die Navigationsleiste.
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 ) } } }
Es ist besonders zu beachten, dass bottomNavigation in diesem Beispiel eine Erweiterungsfunktion ist, die die folgende Form hat:
inline fun ViewManager.bottomNavigation(init: BottomNavigationView.() -> Unit = {}) = ankoView({ BottomNavigationView(it) }, theme = 0, init = init)
Jetzt müssen Sie in MainActivity das NavHostFragment-Objekt definieren (siehe Dock):
private val host by lazy { NavHostFragment.create(R.navigation.navigation_graph) }
Und definieren Sie in der onCreate () -Methode:
supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, host) .setPrimaryNavigationFragment(host) .commit()
Der letzte Schliff: Fügen Sie der onStart () MainActivity ein Objekt der NavController-Klasse hinzu, mit dem Sie zwischen Fragmenten wechseln können, indem Sie das eine oder andere Navigationsleistenobjekt auswählen:
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") } }
Starten Sie die Anwendung und vois là ...