
В предыдущей статье мы обсудили основы BottomAppBar, который не так давно представили на Google I/O 2018 как часть Material компонентов для Android. Мы рассмотрели способ реализации BottomAppBar и изучили его атрибуты. Также BottomAppBar может отображать элементы меню и элемент управления Navigation Drawer, которые раньше мы использовали в тулбаре.

Теперь элементы меню и элемент управления Navigation Drawer должны быть частью BottomAppBar. А сейчас давайте посмотрим, как использовать меню и Navigation Drawer при помощи BottomAppBar.
Меню BottomAppBar
Сначала необходимо создать .xml файл в каталоге res/menu для элементов меню, которые должны быть показаны в BottomAppBar. Вот мой файл bottomappbar_menu.xml:
<?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_fav" android:icon="@drawable/baseline_favorite_white_24" android:title="@string/action_favorite" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_search" android:icon="@drawable/baseline_search_white_24" android:title="@string/action_search" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_settings" android:title="@string/action_settings" app:showAsAction="never"/> </menu>
В MainActivity, в которой вы вызываете setSupportActionBar(bottom_app_bar), добавьте следующий код в метод:
override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater = menuInflater inflater.inflate(R.menu.bottomappbar_menu, menu) return true }
Теперь элементы меню должны отображаться в BottomAppBar.
Обработка кликов по элементам меню
Для обработки кликов по элементам меню необходимо добавить следующий код в MainActivity:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item!!.itemId) { R.id.app_bar_fav -> toast("Fav menu item is clicked!") R.id.app_bar_search -> toast("Search menu item is clicked!") R.id.app_bar_settings -> toast("Settings item is clicked!") } return true }
Теперь меню в BottomAppBar настроено и должно функционировать правильно:

Элемент управления Navigation Drawer в BottomAppBar
Обычно Navigation Drawer реализуется при помощи NavigationView, расположенного в левой части приложения. С BottomAppBar поведение Navigation Drawer изменилось. Теперь Navigation Drawer представляет собой модальное окно в нижней части приложения.

Сперва необходимо создать само модальное окно:
fragment_bottomsheet.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <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_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:menu="@menu/bottom_nav_drawer_menu"/> </androidx.constraintlayout.widget.ConstraintLayout>
Файл меню для Navigation Drawer также должен быть расположен в res/menu.
bottom_nav_drawer_menu.xml
<?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_exposure_plus_1_black_24" android:title="@string/nav_item1" /> <item android:id="@+id/nav2" android:icon="@drawable/baseline_replay_10_black_24" android:title="@string/nav_item2" /> <item android:id="@+id/nav3" android:icon="@drawable/baseline_forward_10_black_24" android:title="@string/nav_item3" /> </group> </menu>
Затем нужно создать класс, расширяющий BottomSheetDialogFragment, который и будет создавать модальное окно:
import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.android.material.bottomsheet.BottomSheetDialogFragment class BottomNavigationDrawerFragment: BottomSheetDialogFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_bottomsheet, container, false) } }
Следующие строки кода нужно добавить в метод onOptionsItemSelected, который используется для обработки кликов по элементам меню. При клике по значку навигации будет создаваться экземпляр объекта BottomNavigationDrawerFragment и отображаться Navigation View.
android.R.id.home -> { val bottomNavDrawerFragment = BottomNavigationDrawerFragment() bottomNavDrawerFragment.show(supportFragmentManager, bottomNavDrawerFragment.tag) }
Вот код макета MainActivity:
activity_main.xml
<?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:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <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:backgroundTint="@color/colorPrimary" app:fabAlignmentMode="center" app:fabAttached="true" app:navigationIcon="@drawable/baseline_menu_white_24"/> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/baseline_add_white_24" app:layout_anchor="@id/bottom_app_bar" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.constraintlayout.widget.ConstraintLayout>
А для кликов по элементам в окне Navigation Drawer вы можете использовать следующий код внутри класса BottomNavigationDrawerFragment:
navigation_view.setNavigationItemSelectedListener { menuItem -> // Bottom Navigation Drawer menu item clicks when (menuItem!!.itemId) { R.id.nav1 -> context!!.toast(getString(R.string.nav1_clicked)) R.id.nav2 -> context!!.toast(getString(R.string.nav2_clicked)) R.id.nav3 -> context!!.toast(getString(R.string.nav3_clicked)) } true }

Полный исходный код этой статьи можно найти на Github. Для тех, кого заинтересовала эта тема, читайте предыдущую часть этой статьи и следующую.
← Реализация BottomAppBar. Часть 1: Material компоненты для Android
→ Реализация BottomAppBar. Часть 3: Поведения для Android
