Android Studio: урок Kotlin — выдвижное меню с DrawerLayout

Боковые панели, выезжающие слева по свайпу или нажатию на иконку гамбургера, уже много лет остаются привычным элементом мобильной навигации. В Android за них отвечает компонент DrawerLayout, который позволяет спрятать меню за краем экрана и показывать его по требованию пользователя. В этом занятии для Android Studio мы с помощью языка Kotlin разберём, как добавить такую выдвижную панель и наполнить её пунктами. Материал рассчитан на начинающих и не требует предварительного знакомства с Navigation Component.


Что такое DrawerLayout и как он работает

DrawerLayout — это корневой контейнер, внутри которого размещают две секции: основное содержимое экрана и скрытое боковое меню. Меню можно открыть свайпом от левого края или нажатием на иконку в верхней панели. По умолчанию панель выезжает слева, но можно настроить и правый край. Компонент входит в библиотеку AndroidX и не требует дополнительных зависимостей.

Для наполнения бокового меню обычно используют NavigationView — готовый элемент из Material Design, который отображает вертикальный список пунктов с иконками. Щелчок по пункту обрабатывается через слушатель setNavigationItemSelectedListener, где по id пункта можно открыть нужный экран или выполнить действие.


Добавление DrawerLayout в разметку

В файле activity_main.xml замените корневой элемент на DrawerLayout. Внутрь поместите основную часть экрана (например, LinearLayout с TextView) и NavigationView. Последний обязательно должен иметь атрибут android:layout_gravity="start" — это говорит системе, что меню выдвигается слева.

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Главный экран"
            android:textSize="24sp" />
    </LinearLayout>
    
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>

Создание меню для NavigationView

В папке res/menu создайте файл drawer_menu.xml. В нём перечислите пункты боковой панели. Каждый пункт имеет id, иконку и название. Для простоты используем системные иконки.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="Главная" />
        <item
            android:id="@+id/nav_settings"
            android:icon="@android:drawable/ic_menu_preferences"
            android:title="Настройки" />
        <item
            android:id="@+id/nav_about"
            android:icon="@android:drawable/ic_menu_info_details"
            android:title="О программе" />
    </group>
</menu>

Обработка выбора пункта в Activity

В MainActivity.kt получим ссылки на DrawerLayout и NavigationView. Установим слушатель выбора пунктов: при клике будем показывать всплывающее сообщение с названием выбранного раздела и закрывать боковое меню.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val drawerLayout = findViewById<DrawerLayout>(R.id.drawerLayout)
        val navigationView = findViewById<NavigationView>(R.id.navigationView)

        navigationView.setNavigationItemSelectedListener { menuItem ->
            when (menuItem.itemId) {
                R.id.nav_home -> showMessage("Главная")
                R.id.nav_settings -> showMessage("Настройки")
                R.id.nav_about -> showMessage("О программе")
            }
            drawerLayout.closeDrawers()
            true
        }
    }

    private fun showMessage(text: String) {
        Toast.makeText(this, "Выбран раздел: $text", Toast.LENGTH_SHORT).show()
    }
}

Метод closeDrawers() плавно убирает панель обратно за край экрана. Возвращая true, мы сообщаем, что событие обработано.


Открытие и закрытие DrawerLayout программно

Иногда нужно открыть или закрыть боковую панель не по свайпу, а по нажатию на иконку в тулбаре. Для этого у DrawerLayout есть методы openDrawer(GravityCompat.START) и closeDrawer(GravityCompat.START). Их можно привязать к кнопке, расположенной в верхней панели.

btnMenu.setOnClickListener {
    drawerLayout.openDrawer(GravityCompat.START)
}

При использовании ActionBarDrawerToggle открытие и закрытие синхронизируется автоматически, но для простого урока достаточно ручного управления.


Советы для начинающих

  • Не перегружайте меню. Оптимальное количество пунктов — от трёх до пяти. Если разделов больше, подумайте о вложенном меню или отдельном экране настроек.
  • Используйте NavigationView. Он автоматически обрабатывает выделение активного пункта, добавляет разделители и поддерживает иконки — не изобретайте велосипед с LinearLayout вручную.
  • Проверяйте жесты на реальном устройстве. На эмуляторе свайп иногда срабатывает не с первого раза, особенно если не настроена скорость курсора.

Коротко о главном

В этом уроке Android Studio на Kotlin вы узнали, как интегрировать в приложение привычную боковую панель с использованием DrawerLayout и NavigationView. Вы создали меню, состоящее из трёх разделов, настроили обработку нажатий и освоили методы программного управления открытием и закрытием панели. Теперь ваше приложение предоставляет пользователю удобную навигацию без перегрузки основного экрана. Попробуйте заменить Toast реальными переходами между фрагментами — это станет логическим продолжением сегодняшнего занятия.