Drawer — что это, DrawerLayout и боковое меню в приложениях

Автор: IT Sectr Опубликовано: 2026-02-23 Время чтения: 12 мин

Drawer (Navigation Drawer) — интерактивная панель, выдвигающаяся с левого (или правого) края экрана и отображающая навигационные ссылки. На Android реализуется через DrawerLayout, на iOS — через кастомные решения вроде SideMenu или стандартный UISplitViewController на iPad. Подробнее о спецификации читайте в документации Material Design 3.

Главное

  • Drawer — боковое меню навигации, выдвигающееся по свайпу или нажатию на иконку «гамбургер»
  • DrawerLayout — стандартный контейнер Android для реализации выдвижного меню
  • SideMenu — популярная библиотека iOS для кастомизируемого бокового меню
  • Modal Drawer — перекрывает контент, используется для фокуса на навигации
  • Standard Drawer — сдвигает контент вправо, оставляя часть видимой

Что такое Drawer?

Drawer (Navigation Drawer) — элемент навигации в виде панели, выдвигающейся из левого края экрана по жесту свайпа или нажатию на иконку «гамбургер» (три горизонтальные линии). Drawer содержит навигационные ссылки, заголовок и опциональные элементы: аватар пользователя, счётчики уведомлений, разделители. Панель может перекрывать контент (Modal) или сдвигать его (Standard).

Material Design 3 (2026) определяет Navigation Drawer как компонент для приложений с 6+ навигационными пунктами. В отличие от Bottom Navigation, Drawer не занимает постоянное место на экране и показывается только по запросу пользователя. Это освобождает пространство для контента, но требует дополнительного действия для открытия. Google рекомендует Drawer для приложений с глубокой иерархией разделов.

Исследование UX Planet (2025) показало: Drawer подходит для приложений с 5–15 разделами, но время навигации на 40% выше, чем при Bottom Navigation. Пользователи пропускают пункты меню, расположенные ниже сгиба экрана (scroll). Поэтому важные разделы должны быть в верхней части Drawer, а менее важные (О приложении, Настройки) — в нижней, отделённые разделителем.

Типы Drawer: Modal и Standard

Modal Drawer — выдвигается поверх контента, затемняя фон. Используется для мобильных устройств, где экран ограничен по ширине. После выбора пункта Drawer автоматически закрывается. Standard Drawer (Permanent) — фиксированная панель, видимая постоянно, сдвигающая контент. Используется на планшетах и десктопе с шириной экрана от 900 dp. Material 3 также определяет Rail Drawer — компактная версия для планшетов, показывающая только иконки.

ТипПоведениеИспользование
ModalПерекрывает контент, затемняет фонТелефоны, временная навигация
StandardСдвигает контент, фиксированПланшеты, десктоп (900+ dp)
RailКомпактная боковая панель с иконкамиПланшеты, адаптивная навигация

DrawerLayout в Android

DrawerLayout — стандартный ViewGroup в Android, реализующий выдвижное боковое меню. DrawerLayout содержит два дочерних элемента: первый — основной контент (FrameLayout с NavHostFragment), второй — NavigationView с меню. DrawerLayout обрабатывает жесты свайпа и программное открытие/закрытие через ActionBarDrawerToggle.

kotlin
// Активити с DrawerLayout и NavigationView
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var drawerLayout: DrawerLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        drawerLayout = binding.drawerLayout
        val navView = binding.navView
        val navController = findNavController(R.id.nav_host_fragment)

        // Связывание Drawer с Navigation Component
        NavigationUI.setupActionBarWithNavController(
            this, navController, drawerLayout
        )
        NavigationUI.setupWithNavController(navView, navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        return NavigationUI.navigateUp(
            findNavController(R.id.nav_host_fragment),
            drawerLayout
        )
    }
}

// XML: activity_main.xml
// <androidx.drawerlayout.widget.DrawerLayout
//   android:id="@+id/drawerLayout"
//   ...>
//   <!-- Основной контент -->
//   <FrameLayout android:id="@+id/nav_host_fragment"
//     android:layout_width="match_parent"
//     android:layout_height="match_parent" />
//   <!-- Navigation Drawer -->
//   <com.google.android.material.navigation.NavigationView
//     android:id="@+id/navView"
//     android:layout_width="wrap_content"
//     android:layout_height="match_parent"
//     android:layout_gravity="start"
//     app:menu="@menu/nav_menu" />
// </androidx.drawerlayout.widget.DrawerLayout>

NavigationView — компонент Material Design для содержимого Drawer. Он поддерживает заголовок (headerLayout), пункты меню (menu), подзаголовки, чекбоксы и флажки. Атрибут app:menu указывает на XML-меню с пунктами навигации. NavigationUI автоматически подсвечивает активный пункт и синхронизирует состояние с NavController.

Side Menu в iOS

В iOS нет встроенного компонента «Drawer» — Apple не рекомендует боковое меню для iPhone (HIG, 2026). Однако для iPad используется UISplitViewController с primary и secondary панелями. Для iPhone боковое меню реализуется через сторонние библиотеки (SideMenu, SwiftUI-side-menu) или кастомные решения с offset контента. В SwiftUI боковое меню создаётся через ZStack с анимацией offset.

swift
import SwiftUI

struct DrawerView<Content: View, Menu: View>: View {
    let menuWidth: CGFloat = 280

    @Binding var isOpen: Bool
    @ViewBuilder let content: Content
    @ViewBuilder let menu: Menu

    var body: some View {
        ZStack(alignment: .leading) {
            content
                .offset(x: isOpen ? menuWidth : 0)
                .animation(.easeInOut, value: isOpen)

            if isOpen {
                menu
                    .frame(width: menuWidth)
                    .transition(.move(edge: .leading))

                Color.black.opacity(0.3)
                    .ignoresSafeArea()
                    .onTapGesture { isOpen = false }
            }
        }
    }
}

// Использование
struct ContentView: View {
    @State private var showDrawer = false

    var body: some View {
        DrawerView(isOpen: $showDrawer) {
            NavigationStack {
                HomeView()
                    .toolbar {
                        ToolbarItem(placement: .navigationBarLeading) {
                            Button(action: { showDrawer.toggle() }) {
                                Image(systemName: "line.horizontal.3")
                            }
                        }
                    }
            }
        } menu: {
            DrawerMenuView()
        }
    }
}

Для production-проектов на iOS часто используется библиотека SideMenu (GitHub, 8k+ stars). Она предоставляет готовый UIViewController с поддержкой жестов, блюра фона, кастомной ширины и анимаций. SideMenu поддерживает левое и правое меню, множественные уровни и интеграцию с UIKit через UINavigationController. Альтернатива — UISplitViewController на iPad (системный, без кастомных анимаций).

Кастомизация Drawer: заголовок, иконки, секции

Drawer допускает широкую кастомизацию. В Android NavigationView поддерживает headerLayout — кастомный layout, размещаемый над пунктами меню. В нём размещают аватар, имя пользователя, email и обложку. Пункты меню группируются через <menu> с подзаголовками, разделителями и флажками. На iOS кастомизация SideMenu включает настройку цвета фона, блюра, ширины и углов скругления.

kotlin
// Кастомный header для NavigationView
val headerView = binding.navView.inflateHeaderView(R.layout.nav_header)
headerView.findViewById<ImageView>(R.id.iv_avatar)
    .setImageResource(R.drawable.avatar)
headerView.findViewById<TextView>(R.id.tv_name)
    .text = "John Doe"

// Настройка пунктов меню
val menuItem = binding.navView.menu.findItem(R.id.nav_notifications)
menuItem.isChecked = true

// Добавление бейджа
val badge = binding.navView.getOrCreateBadge(R.id.nav_notifications)
badge.number = 15
badge.isVisible = true

Материальный дизайн рекомендует следующую структуру Drawer: заголовок (имя, аватар), основные навигационные пункты (5–8), разделитель, второстепенные пункты (Настройки, Помощь), футер (О приложении, версия). В Material 3 NavigationView также поддерживает кастомную подсветку активного пункта через itemShape и itemBackground.

Когда использовать Drawer: UX-рекомендации

Drawer эффективен для приложений с 6+ разделами, настройками и страницами справки. Не подходит для приложений, где быстрый доступ к разделам критичен — в таких случаях лучше Bottom Navigation. Material Design рекомендует комбинировать Drawer с Bottom Navigation: основная навигация — Bottom (3–5 вкладок), дополнительная — Drawer (настройки, справка, о приложении).

Основные ошибки при реализации Drawer: перегруженное меню (15+ пунктов без группировки), скрытие важных разделов ниже сгиба, отсутствие иконок (текст без иконок медленнее сканируется на 30%), анимация с задержками (должна быть ≤ 200 ms). Лучшие практики: заголовок с именем пользователя, иконки у каждого пункта, разделители между группами, подсветка активного раздела, поддержка жеста свайпа для открытия.

  • 6+ разделов — Drawer оправдан, меньше — используйте Bottom Navigation
  • Иконки — обязательны для каждого пункта, ускоряют визуальный поиск
  • Группировка — разделители между основными и второстепенными пунктами
  • Заголовок — аватар, имя и email для персонализации (социальные приложения)
  • Жест свайпа — обязателен для открытия, дублируется кнопкой «гамбургер»

Часто задаваемые вопросы

Чем Drawer отличается от Bottom Navigation?

Drawer — скрытое боковое меню, открываемое жестом, подходит для 6+ разделов и глубокой иерархии. Bottom Navigation — всегда видимая нижняя панель для 3–5 разделов. Drawer экономит экранное пространство, но требует дополнительного действия для открытия, что увеличивает время навигации на 40%.

Как добавить Drawer в SwiftUI?

В SwiftUI нет встроенного Drawer. Используйте ZStack с offset контента и анимацией, как в примере выше. Для production применяются библиотеки: SideMenu (Swift Package) или кастомная обёртка над UISplitViewController. На iPad используйте UISplitViewController с preferredDisplayMode .oneBesideSecondary.

Почему Apple не рекомендует Drawer на iPhone?

Apple HIG (2026) утверждает: боковое меню скрывает контент и нарушает принцип прямой манипуляции. iOS рекомендует Tab Bar для навигации. Drawer на iPhone используется только для настроек и дополнительных действий, не для основной навигации. На iPad Drawer заменяется UISplitViewController, который является системным стандартом.

Как обработать жест свайпа для Drawer?

В Android DrawerLayout автоматически обрабатывает свайп от левого края. В iOS кастомный Drawer требует UIPanGestureRecognizer либо Edge Pan Gesture (SwiftUI — .gesture с DragGesture). Важно: свайп должен конфликтовать с системным свайпом «Назад» — на iOS левый край занят системным жестом.

Можно ли сделать Drawer с правой стороны?

Да. В Android укажите android:layout_gravity="end" для NavigationView. На iOS создайте меню с edge: .trailing. Правосторонний Drawer используется реже — для дополнительных опций, фильтров или чатов. Основная навигация остаётся слева в соответствии с Material Design и ожиданиями пользователей.

Итоги

  • Drawer — боковое меню навигации для 6+ разделов, выдвигающееся по свайпу или нажатию на «гамбургер»
  • DrawerLayout (Android) — стандартный ViewGroup с интеграцией Navigation Component через NavigationUI
  • SideMenu (iOS) — популярная библиотека для кастомного Drawer, так как Apple не предоставляет встроенного компонента
  • Modal vs Standard — Modal перекрывает контент (телефоны), Standard сдвигает контент (планшеты 900+ dp)
  • Кастомизация — заголовок с аватаром, группировка пунктов, бейджи, подсветка активного раздела
  • UX — Drawer на 40% медленнее Bottom Navigation, но необходим для приложений с глубокой иерархией
  • Материал 3 — NavigationView поддерживает стили, иконки, бейджи и кастомный header layout

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также