Drawer (Navigation Drawer) — interaktywny panel wysuwany z lewej (lub prawej) krawędzi ekranu, wyświetlający linki nawigacyjne. W Android jest implementowany przez DrawerLayout, w iOS — przez niestandardowe rozwiązania, takie jak SideMenu, lub standardowy UISplitViewController na iPadzie. Więcej informacji o specyfikacji znajdziesz w dokumentacji Material Design 3.
Najważniejsze
Drawer (Navigation Drawer) — element nawigacji w postaci panelu wysuwanego z lewej krawędzi ekranu za pomocą gestu przesunięcia lub kliknięcia ikony „hamburgera” (trzy poziome linie). Drawer zawiera linki nawigacyjne, nagłówek oraz opcjonalne elementy: awatar użytkownika, liczniki powiadomień, separatory. Panel może nakładać się na treść (Modal) lub ją przesuwać (Standard).
Material Design 3 (2026) definiuje Navigation Drawer jako komponent dla aplikacji z 6+ punktami nawigacyjnymi. W przeciwieństwie do Bottom Navigation, Drawer nie zajmuje stałego miejsca na ekranie i jest wyświetlany tylko na żądanie użytkownika. Zwolnia to miejsce na treść, ale wymaga dodatkowej czynności do otwarcia. Google zaleca Drawer dla aplikacji z głęboką hierarchią sekcji.
Badanie UX Planet (2025) wykazało: Drawer sprawdza się w aplikacjach z 5–15 sekcjami, ale czas nawigacji jest o 40% wyższy niż w przypadku Bottom Navigation. Użytkownicy pomijają pozycje menu znajdujące się poniżej widocznej części ekranu (scroll). Dlatego ważne sekcje powinny znajdować się w górnej części Drawer, a mniej ważne (O aplikacji, Ustawienia) — w dolnej, oddzielone separatorem.
Modal Drawer — wysuwa się na wierzch treści, przyciemniając tło. Używany na urządzeniach mobilnych, gdzie ekran ma ograniczoną szerokość. Po wybraniu pozycji Drawer automatycznie się zamyka. Standard Drawer (Permanent) — stały panel, widoczny przez cały czas, przesuwający treść. Używany na tabletach i komputerach z szerokością ekranu od 900 dp. Material 3 definiuje również Rail Drawer — kompaktową wersję dla tabletów, pokazującą tylko ikony.
| Typ | Zachowanie | Zastosowanie |
|---|---|---|
| Modal | Nakłada się na treść, przyciemnia tło | Telefony, tymczasowa nawigacja |
| Standard | Przesuwa treść, stały | Tablety, komputery (900+ dp) |
| Rail | Kompaktowy panel boczny z ikonami | Tablety, nawigacja adaptacyjna |
DrawerLayout — standardowa ViewGroup w Android implementująca wysuwane boczne menu. DrawerLayout zawiera dwa elementy potomne: pierwszy — główna treść (FrameLayout z NavHostFragment), drugi — NavigationView z menu. DrawerLayout obsługuje gesty przesunięcia oraz programowe otwieranie/zamykanie za pomocą ActionBarDrawerToggle.
// Aktywność z DrawerLayout i 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)
// Powiązanie Drawer z 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"
// ...>
// <!-- Główna treść -->
// <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 — komponent Material Design do zawartości Drawer. Obsługuje nagłówek (headerLayout), pozycje menu (menu), podtytuły, checkboxy i znaczniki. Atrybut app:menu wskazuje na XML-menu z pozycjami nawigacyjnymi. NavigationUI automatycznie podświetla aktywną pozycję i synchronizuje stan z NavController.
W iOS nie ma wbudowanego komponentu „Drawer” — Apple nie zaleca bocznego menu dla iPhone'a (HIG, 2026). Jednak dla iPada używany jest UISplitViewController z panelem primary i secondary. Dla iPhone'a boczne menu implementuje się za pomocą bibliotek zewnętrznych (SideMenu, SwiftUI-side-menu) lub niestandardowych rozwiązań z offsetem treści. W SwiftUI boczne menu tworzy się przez ZStack z animacją 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 }
}
}
}
}
// Użycie
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()
}
}
}W projektach produkcyjnych na iOS często używa się biblioteki SideMenu (GitHub, 8k+ gwiazdek). Oferuje gotowy UIViewController z obsługą gestów, rozmyciem tła, niestandardową szerokością i animacjami. SideMenu obsługuje lewe i prawe menu, wiele poziomów i integrację z UIKit przez UINavigationController. Alternatywa — UISplitViewController na iPadzie (systemowy, bez niestandardowych animacji).
Drawer pozwala na szeroką personalizację. W Android NavigationView obsługuje headerLayout — niestandardowy layout umieszczany nad pozycjami menu. Umieszcza się w nim awatar, nazwę użytkownika, email i okładkę. Pozycje menu grupuje się przez <menu> z podtytułami, separatorami i znacznikami. W iOS dostosowywanie SideMenu obejmuje ustawienie koloru tła, rozmycia, szerokości i zaokrąglenia rogów.
// Niestandardowy header dla 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"
// Konfiguracja pozycji menu
val menuItem = binding.navView.menu.findItem(R.id.nav_notifications)
menuItem.isChecked = true
// Dodawanie badge'a
val badge = binding.navView.getOrCreateBadge(R.id.nav_notifications)
badge.number = 15
badge.isVisible = trueMaterial Design zaleca następującą strukturę Drawer: nagłówek (nazwa, awatar), główne pozycje nawigacyjne (5–8), separator, drugorzędne pozycje (Ustawienia, Pomoc), stopka (O aplikacji, wersja). W Material 3 NavigationView obsługuje również niestandardowe podświetlenie aktywnej pozycji przez itemShape i itemBackground.
Drawer jest efektywny dla aplikacji z 6+ sekcjami, ustawieniami i stronami pomocy. Nie nadaje się do aplikacji, gdzie szybki dostęp do sekcji jest krytyczny — w takich przypadkach lepsza jest Bottom Navigation. Material Design zaleca łączenie Drawer z Bottom Navigation: główna nawigacja — Bottom (3–5 zakładek), dodatkowa — Drawer (ustawienia, pomoc, o aplikacji).
Główne błędy przy implementacji Drawer: przeładowane menu (15+ pozycji bez grupowania), ukrywanie ważnych sekcji poniżej widocznego obszaru, brak ikon (tekst bez ikon jest skanowany o 30% wolniej), animacja z opóźnieniami (powinna być ≤ 200 ms). Najlepsze praktyki: nagłówek z nazwą użytkownika, ikony przy każdej pozycji, separatory między grupami, podświetlenie aktywnej sekcji, obsługa gestu przesunięcia do otwierania.
Często zadawane pytania
Drawer — ukryte boczne menu otwierane gestem, odpowiednie dla 6+ sekcji i głębokiej hierarchii. Bottom Navigation — zawsze widoczny dolny panel dla 3–5 sekcji. Drawer oszczędza miejsce na ekranie, ale wymaga dodatkowej czynności do otwarcia, co zwiększa czas nawigacji o 40%.
SwiftUI nie ma wbudowanego Drawer. Użyj ZStack z offsetem treści i animacją, jak w przykładzie powyżej. W projektach produkcyjnych stosuje się biblioteki: SideMenu (Swift Package) lub niestandardowe opakowanie UISplitViewController. Na iPadzie użyj UISplitViewController z preferredDisplayMode .oneBesideSecondary.
Apple HIG (2026) stwierdza: boczne menu ukrywa treść i narusza zasadę bezpośredniej manipulacji. iOS zaleca Tab Bar do nawigacji. Drawer na iPhone jest używany tylko do ustawień i dodatkowych działań, nie do głównej nawigacji. Na iPadzie Drawer jest zastępowany przez UISplitViewController, który jest standardem systemowym.
W Android DrawerLayout automatycznie obsługuje przesunięcie od lewej krawędzi. W iOS niestandardowy Drawer wymaga UIPanGestureRecognizer lub Edge Pan Gesture (SwiftUI — .gesture z DragGesture). Ważne: przesunięcie może kolidować z systemowym gestem „Wstecz” — na iOS lewa krawędź jest zajęta przez gest systemowy.
Tak. W Android ustaw android:layout_gravity="end" dla NavigationView. W iOS utwórz menu z edge: .trailing. Prawostronny Drawer jest używany rzadziej — do dodatkowych opcji, filtrów lub czatów. Główna nawigacja pozostaje po lewej stronie zgodnie z Material Design i oczekiwaniami użytkowników.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również