Drawer (Navigation Drawer) is an interactive panel that slides out from the left (or right) edge of the screen and displays navigation links. On Android it is implemented via DrawerLayout, on iOS — via custom solutions like SideMenu or the standard UISplitViewController on iPad. Read more about the specification in the Material Design 3 documentation.
Key Takeaways
Drawer (Navigation Drawer) is a navigation element in the form of a panel that slides out from the left edge of the screen via a swipe gesture or tap on the hamburger icon (three horizontal lines). The Drawer contains navigation links, a header, and optional elements: user avatar, notification badges, dividers. The panel can overlay content (Modal) or shift it (Standard).
Material Design 3 (2026) defines Navigation Drawer as a component for apps with 6+ navigation items. Unlike Bottom Navigation, the Drawer does not take up permanent screen space and is shown only on user request. This frees up space for content but requires an additional action to open. Google recommends Drawer for apps with deep section hierarchy.
UX Planet research (2025) showed: Drawer is suitable for apps with 5–15 sections, but navigation time is 40% higher than with Bottom Navigation. Users miss menu items located below the screen fold (scroll). Therefore important sections should be at the top of the Drawer, and less important ones (About, Settings) at the bottom, separated by a divider.
Modal Drawer slides out over the content, dimming the background. Used for mobile devices where screen width is limited. After selecting an item, the Drawer automatically closes. Standard Drawer (Permanent) is a fixed panel that is always visible, shifting the content. Used on tablets and desktop with screen width from 900 dp. Material 3 also defines Rail Drawer — a compact version for tablets showing only icons.
| Type | Behavior | Usage |
|---|---|---|
| Modal | Overlays content, dims background | Phones, temporary navigation |
| Standard | Shifts content, fixed | Tablets, desktop (900+ dp) |
| Rail | Compact side panel with icons | Tablets, adaptive navigation |
DrawerLayout is the standard ViewGroup in Android that implements a sliding side menu. DrawerLayout contains two child elements: the first — main content (FrameLayout with NavHostFragment), the second — NavigationView with the menu. DrawerLayout handles swipe gestures and programmatic open/close via ActionBarDrawerToggle.
// Activity with DrawerLayout and 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)
// Binding Drawer with 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"
// ...>
// <!-- Main content -->
// <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 is a Material Design component for Drawer content. It supports header (headerLayout), menu items (menu), subheaders, checkboxes, and switches. The app:menu attribute points to an XML menu with navigation items. NavigationUI automatically highlights the active item and synchronizes state with NavController.
iOS does not have a built-in "Drawer" component — Apple does not recommend a side menu for iPhone (HIG, 2026). However, for iPad, UISplitViewController with primary and secondary panels is used. For iPhone, the side menu is implemented via third-party libraries (SideMenu, SwiftUI-side-menu) or custom solutions with content offset. In SwiftUI, a side menu is created via ZStack with offset animation.
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 }
}
}
}
}
// Usage
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()
}
}
}For production iOS projects, the SideMenu library is often used (GitHub, 8k+ stars). It provides a ready-made UIViewController with gesture support, background blur, custom width, and animations. SideMenu supports left and right menus, multiple levels, and UIKit integration via UINavigationController. An alternative is UISplitViewController on iPad (system, without custom animations).
Drawer allows extensive customization. In Android, NavigationView supports headerLayout — a custom layout placed above menu items. It can contain avatar, username, email, and cover image. Menu items are grouped via <menu> with subheaders, dividers, and switches. On iOS, SideMenu customization includes background color, blur, width, and corner radius settings.
// Custom header for 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"
// Configuring menu items
val menuItem = binding.navView.menu.findItem(R.id.nav_notifications)
menuItem.isChecked = true
// Adding a badge
val badge = binding.navView.getOrCreateBadge(R.id.nav_notifications)
badge.number = 15
badge.isVisible = trueMaterial Design recommends the following Drawer structure: header (name, avatar), main navigation items (5–8), divider, secondary items (Settings, Help), footer (About, version). In Material 3, NavigationView also supports custom active item highlighting via itemShape and itemBackground.
Drawer is effective for apps with 6+ sections, settings, and help pages. It is not suitable for apps where quick access to sections is critical — in such cases Bottom Navigation is better. Material Design recommends combining Drawer with Bottom Navigation: main navigation — Bottom (3–5 tabs), additional — Drawer (settings, help, about).
Common mistakes when implementing Drawer: overloaded menu (15+ items without grouping), hiding important sections below the fold, lack of icons (text without icons is 30% slower to scan), animation delays (should be ≤ 200 ms). Best practices: header with username, icons for each item, dividers between groups, active section highlighting, swipe gesture support for opening.
Frequently Asked Questions
Drawer is a hidden side menu opened by gesture, suitable for 6+ sections and deep hierarchy. Bottom Navigation is an always-visible bottom bar for 3–5 sections. Drawer saves screen space but requires an additional action to open, increasing navigation time by 40%.
SwiftUI does not have a built-in Drawer. Use ZStack with content offset and animation as shown in the example above. For production, libraries are used: SideMenu (Swift Package) or a custom wrapper over UISplitViewController. On iPad, use UISplitViewController with preferredDisplayMode .oneBesideSecondary.
Apple HIG (2026) states: the side menu hides content and violates the direct manipulation principle. iOS recommends Tab Bar for navigation. Drawer on iPhone is used only for settings and additional actions, not for main navigation. On iPad, Drawer is replaced by UISplitViewController, which is the system standard.
In Android, DrawerLayout automatically handles swipe from the left edge. In iOS, a custom Drawer requires UIPanGestureRecognizer or Edge Pan Gesture (SwiftUI — .gesture with DragGesture). Important: the swipe must conflict with the system "Back" swipe — on iOS the left edge is occupied by the system gesture.
Yes. In Android, specify android:layout_gravity="end" for NavigationView. On iOS, create a menu with edge: .trailing. Right-side Drawer is used less often — for additional options, filters, or chats. The main navigation remains on the left according to Material Design and user expectations.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also