Drawer (Navigation Drawer) — интерактивная панель, выдвигающаяся с левого (или правого) края экрана и отображающая навигационные ссылки. На Android реализуется через DrawerLayout, на iOS — через кастомные решения вроде SideMenu или стандартный UISplitViewController на iPad. Подробнее о спецификации читайте в документации Material Design 3.
Главное
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, а менее важные (О приложении, Настройки) — в нижней, отделённые разделителем.
Modal Drawer — выдвигается поверх контента, затемняя фон. Используется для мобильных устройств, где экран ограничен по ширине. После выбора пункта Drawer автоматически закрывается. Standard Drawer (Permanent) — фиксированная панель, видимая постоянно, сдвигающая контент. Используется на планшетах и десктопе с шириной экрана от 900 dp. Material 3 также определяет Rail Drawer — компактная версия для планшетов, показывающая только иконки.
| Тип | Поведение | Использование |
|---|---|---|
| Modal | Перекрывает контент, затемняет фон | Телефоны, временная навигация |
| Standard | Сдвигает контент, фиксирован | Планшеты, десктоп (900+ dp) |
| Rail | Компактная боковая панель с иконками | Планшеты, адаптивная навигация |
DrawerLayout — стандартный ViewGroup в Android, реализующий выдвижное боковое меню. DrawerLayout содержит два дочерних элемента: первый — основной контент (FrameLayout с NavHostFragment), второй — NavigationView с меню. DrawerLayout обрабатывает жесты свайпа и программное открытие/закрытие через ActionBarDrawerToggle.
// Активити с 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.
В iOS нет встроенного компонента «Drawer» — Apple не рекомендует боковое меню для iPhone (HIG, 2026). Однако для iPad используется UISplitViewController с primary и secondary панелями. Для iPhone боковое меню реализуется через сторонние библиотеки (SideMenu, SwiftUI-side-menu) или кастомные решения с offset контента. В SwiftUI боковое меню создаётся через ZStack с анимацией offset.
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 допускает широкую кастомизацию. В Android NavigationView поддерживает headerLayout — кастомный layout, размещаемый над пунктами меню. В нём размещают аватар, имя пользователя, email и обложку. Пункты меню группируются через <menu> с подзаголовками, разделителями и флажками. На iOS кастомизация SideMenu включает настройку цвета фона, блюра, ширины и углов скругления.
// Кастомный 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 эффективен для приложений с 6+ разделами, настройками и страницами справки. Не подходит для приложений, где быстрый доступ к разделам критичен — в таких случаях лучше Bottom Navigation. Material Design рекомендует комбинировать Drawer с Bottom Navigation: основная навигация — Bottom (3–5 вкладок), дополнительная — Drawer (настройки, справка, о приложении).
Основные ошибки при реализации Drawer: перегруженное меню (15+ пунктов без группировки), скрытие важных разделов ниже сгиба, отсутствие иконок (текст без иконок медленнее сканируется на 30%), анимация с задержками (должна быть ≤ 200 ms). Лучшие практики: заголовок с именем пользователя, иконки у каждого пункта, разделители между группами, подсветка активного раздела, поддержка жеста свайпа для открытия.
Часто задаваемые вопросы
Drawer — скрытое боковое меню, открываемое жестом, подходит для 6+ разделов и глубокой иерархии. Bottom Navigation — всегда видимая нижняя панель для 3–5 разделов. Drawer экономит экранное пространство, но требует дополнительного действия для открытия, что увеличивает время навигации на 40%.
В SwiftUI нет встроенного Drawer. Используйте ZStack с offset контента и анимацией, как в примере выше. Для production применяются библиотеки: SideMenu (Swift Package) или кастомная обёртка над UISplitViewController. На iPad используйте UISplitViewController с preferredDisplayMode .oneBesideSecondary.
Apple HIG (2026) утверждает: боковое меню скрывает контент и нарушает принцип прямой манипуляции. iOS рекомендует Tab Bar для навигации. Drawer на iPhone используется только для настроек и дополнительных действий, не для основной навигации. На iPad Drawer заменяется UISplitViewController, который является системным стандартом.
В Android DrawerLayout автоматически обрабатывает свайп от левого края. В iOS кастомный Drawer требует UIPanGestureRecognizer либо Edge Pan Gesture (SwiftUI — .gesture с DragGesture). Важно: свайп должен конфликтовать с системным свайпом «Назад» — на iOS левый край занят системным жестом.
Да. В Android укажите android:layout_gravity="end" для NavigationView. На iOS создайте меню с edge: .trailing. Правосторонний Drawer используется реже — для дополнительных опций, фильтров или чатов. Основная навигация остаётся слева в соответствии с Material Design и ожиданиями пользователей.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также