
BottomAppBar ist eine der neuen Android Material-Komponenten, die bei Google I / O 2018 eingeführt wurden . Durch Verschieben der Navigationsleiste und des Anwendungsmenüs an den unteren Bildschirmrand ändert BottomAppBar das Erscheinungsbild von Android-Anwendungen radikal.
Im ersten und zweiten Teil unserer Artikelserie über BottomAppBar haben wir uns mit BottomAppBar getroffen und dessen Attribute besprochen. Wir haben auch erklärt, wie Sie Navigationsschubladen- und Anwendungsmenüs in der BottomAppBar implementieren.
Verhalten
Anwendungskomponenten sind laut Material Design nicht statisch. Sie können sich bewegen oder transformieren, d.h. eine Art Verhalten haben. Material Design bildet auch einen Rahmen für dieses Verhalten. In diesem Artikel werden die Implementierungsdetails des empfohlenen Verhaltens für die BottomAppBar erläutert, das auf der Richtlinienseite für die BottomAppBar vorgestellt wird .
Layout
Die erste Richtlinie beschreibt das Layout der BottomAppBar. Folgendes wird vorgeschlagen :
Für Anwendungsbildschirme mit unterschiedlichen Bedeutungen können Sie das Layout und die Menüelemente in BottomAppBar ändern. Sie können beispielsweise mehr oder weniger Menüelemente anzeigen, je nachdem, was für einen bestimmten Bildschirm am besten geeignet ist.

Basierend auf dieser Richtlinie wird empfohlen, das BottomAppBar-Layout auf den Hauptbildschirmen zu verwenden , das mehrere Menüelemente und eine zentrierte FAB (Floating Action Button) anzeigt. Auf den sekundären Bildschirmen , deren Übergang von den Hauptbildschirmen erfolgt, sollte das BottomAppBar-Layout aus einem rechtsbündigen FAB und mehreren zusätzlichen Menüelementen bestehen. Übergänge zwischen diesen beiden Bildschirmen müssen ordnungsgemäß ausgeführt werden. Gif oben demonstriert diese Richtlinie.
Nun wollen wir sehen, wie dieses Verhalten implementiert werden kann. Wir haben zwei XML-Dateien im Ordner res/menu
für das Menü jedes Bildschirms:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/app_bar_search" android:icon="@drawable/baseline_search_white_24" android:title="@string/action_search" app:showAsAction="ifRoom"/> </menu>
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/app_bar_mail" android:icon="@drawable/baseline_mail_white_24" android:title="@string/action_mail" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_delete" android:icon="@drawable/baseline_delete_white_24" android:title="@string/action_delete" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_archieve" android:icon="@drawable/baseline_archive_white_24" android:title="@string/action_archieve" app:showAsAction="ifRoom"/> </menu>
Wenn es einen Übergang zwischen Bildschirmen gibt, z. B. durch Drücken der Taste TOGGLE SCREEN in unserem Fall, sollte sich das Layout der BottomAppBar einschließlich Menü und FAB ändern. Hier ist der Basiscode für dieses Verhalten des BottomAppBar-Layouts:
// Hide navigation drawer icon bottom_app_bar.navigationIcon = null // Move FAB from the center of BottomAppBar to the end of it bottom_app_bar.fabAlignmentMode = BottomAppBar.FAB_ALIGNMENT_MODE_END // Replace the action menu bottom_app_bar.replaceMenu(bottomappbar_menu_secondary) // Change FAB icon fab?.setImageDrawable(baseline_reply_white_24)
Wenn Sie animierte Übergänge vornehmen möchten, benötigen Sie zusätzlichen Code. Sie können den Quellcode studieren, der am Ende dieses Artikels angehängt ist und in dem Sie Animationen finden.
Scrollen
Das Scrollen ist ein wichtiger Verhaltensauslöser für Komponenten wie BottomAppBar. Auf der Seite Richtlinien für das Materialdesign wird für diesen Fall das folgende Verhalten empfohlen:
Beim Scrollen kann eine BottomAppBar angezeigt oder ausgeblendet werden:
- Durch Scrollen nach unten wird die BottomAppBar ausgeblendet. Wenn es FAB hatte, trennt es sich vom Panel und bleibt auf dem Bildschirm.
- Wenn Sie nach oben scrollen, wird die BottomAppBar angezeigt und erneut an das FAB angehängt, falls vorhanden.
Das Folgende ist eine Demonstration des Verhaltens der BottomAppBar beim Scrollen.

Um dieses Verhalten verwenden zu können, müssen BottomAppBar und FAB direkte untergeordnete Elemente von CoordinatorLayout sein . Dann aktivieren wir hideOnScroll und setzen die Bildlaufflags für die BottomAppBar:
<com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottom_app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:fabAlignmentMode="center" app:hideOnScroll="true" app:layout_scrollFlags="scroll|enterAlways"/>
Dies reicht aus, um dieses Verhalten von BottomAppBar zu implementieren.
Höhe
Jede Komponente in der Material Design-Welt hat eine ähnliche Höhe wie unsere physische Welt. In der BottomAppBar beträgt die Höhe 8 dp , und der Inhalt des Bildschirms steigt auf 0 dp . FAB im statischen Zustand steigt um 12dp . Die beiden Komponenten, an die wir uns in diesem Artikel erinnern werden, Navigation Drawer und Snackbar, steigen um 16 dp bzw. 6 dp .
In der Regel ist die Snackbar eine Komponente zur Benachrichtigung des Benutzers, die am unteren Bildschirmrand angezeigt wird. Wenn sich jedoch eine BottomAppBar oder eine Navigationsleiste auf dem Bildschirm befindet, sollte sich das Verhalten der Snackbar ändern. In diesen Fällen sollte die Snackbar über den unteren Komponenten angezeigt werden. Hier ist eine Demo und zugehöriger Code zum Implementieren:

private fun displayMaterialSnackBar() { val marginSide = 0 val marginBottom = 550 val snackbar = Snackbar.make( coordinatorLayout2, "FAB Clicked", Snackbar.LENGTH_LONG ).setAction("UNDO") { }
Wie bereits erwähnt, steigt die Navigationsschublade um 16 dp , was - gemäß der Richtlinie - bedeutet
Menüs, die aus der BottomAppBar herausfallen (z. B. Navigationsschublade), werden als modale Fenster eine Ebene höher als die BottomAppBar selbst geöffnet.
Das Folgende ist die Implementierung unserer Navigationsschublade:

Navigation Drawer ist ein modales Fenster und folgt daher der obigen Implementierungsregel.
Details der Implementierung dieses Verhaltens sind wie folgt. Im Ordner res/menu
muss eine XML-Menüdatei für die Navigationsansicht erstellt werden, die in der Navigationsleiste verwendet wird:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <group android:checkableBehavior="none"> <item android:id="@+id/nav1" android:icon="@drawable/baseline_mail_white_24" android:title="@string/nav_item1" /> <item android:id="@+id/nav2" android:icon="@drawable/baseline_bookmark_white_24" android:title="@string/nav_item2" /> <item android:id="@+id/nav3" android:icon="@drawable/baseline_message_white_24" android:title="@string/nav_item3" /> <item android:id="@+id/nav4" android:icon="@drawable/baseline_note_white_24" android:title="@string/nav_item4" /> <item android:id="@+id/nav5" android:icon="@drawable/baseline_location_on_white_24" android:title="@string/nav_item5" /> <item android:id="@+id/nav6" android:icon="@drawable/baseline_sync_white_24" android:title="@string/nav_item6" /> <item android:id="@+id/nav7" android:icon="@drawable/baseline_cloud_upload_white_24" android:title="@string/nav_item7" /> <item android:id="@+id/nav8" android:icon="@drawable/baseline_favorite_white_24" android:title="@string/nav_item8" /> <item android:id="@+id/nav9" android:icon="@drawable/baseline_chrome_reader_mode_white_24" android:title="@string/nav_item9" /> <item android:id="@+id/nav10" android:icon="@drawable/baseline_select_all_white_24" android:title="@string/nav_item10" /> <item android:id="@+id/nav11" android:icon="@drawable/baseline_sort_white_24" android:title="@string/nav_item11" /> <item android:id="@+id/nav12" android:icon="@drawable/baseline_access_time_white_24" android:title="@string/nav_item12" /> <item android:id="@+id/nav13" android:icon="@drawable/baseline_data_usage_white_24" android:title="@string/nav_item13" /> </group> </menu>
Anschließend sollte mithilfe der Navigationsleiste eine Layoutdatei für das Fragment erstellt werden:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/navigation_view_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:behavior_hideable="true" app:layout_behavior="@string/bottom_sheet_behavior"> <com.google.android.material.navigation.NavigationView android:id="@+id/navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginTop="4dp" android:paddingBottom="40dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/view2" app:menu="@menu/bottom_nav_drawer_menu" app:theme="@style/NavigationDrawerStyle" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="12dp" android:layout_marginTop="16dp" android:fontFamily="@font/rubik_medium" android:text="@string/bottom_sheet_name" android:textColor="@color/colorAccent" android:textSize="18sp" android:textStyle="bold" app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:text="@string/bottom_sheet_email" android:textColor="@color/colorAccent" app:layout_constraintStart_toStartOf="@+id/textView" app:layout_constraintTop_toBottomOf="@+id/textView" /> <ImageView android:id="@+id/imageView" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginStart="24dp" android:background="@drawable/baseline_account_circle_black_48" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/textView" /> <View android:id="@+id/view2" android:layout_width="match_parent" android:layout_height="2dip" android:layout_marginTop="15dp" android:background="#447e7e7e" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView2" /> <ImageView android:id="@+id/close_imageview" android:layout_width="24dp" android:layout_height="24dp" android:layout_marginTop="8dp" android:layout_marginEnd="16dp" android:layout_marginBottom="8dp" android:background="@drawable/baseline_close_black_24" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@+id/textView2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/textView" /> </androidx.constraintlayout.widget.ConstraintLayout>
Diese Layoutdatei enthält die Navigationsansicht und andere Komponenten, aus denen das Layout für die Navigationsleiste besteht. Um dieses Layout zu erstellen, benötigen wir eine Fragmentklasse, die BottomSheetDialogFragment erweitert:
class BottomNavigationDrawerFragment: BottomSheetDialogFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_bottom_navigation_drawer, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigation_view.setNavigationItemSelectedListener { menuItem ->
Wenn Sie auf das Navigationsschubladen-Symbol klicken, wird eine Instanz dieses Fragments erstellt, die als modales Fenster angezeigt wird:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item!!.itemId) { android.R.id.home -> { val bottomNavDrawerFragment = BottomNavigationDrawerFragment() bottomNavDrawerFragment.show(supportFragmentManager, bottomNavDrawerFragment.tag) } } return true }
Dieser Artikel schließt unsere Artikelserie über die BottomAppBar ab. Den Quellcode für diesen Artikel finden Sie auf Github . Kommentieren und Fragen stellen.
← Implementierung von BottomAppBar. Teil 1: Materialkomponenten für Android
← Implementierung von BottomAppBar. Teil 2: Menü- und Navigationsschubladensteuerung