Bottom Navigation — wzorzec nawigacji, w którym panel przełączania sekcji znajduje się w dolnej części ekranu. W Android implementowany przez BottomNavigationView (Material 3), w iOS — przez UITabBarController lub TabView w SwiftUI. Więcej o specyfikacji Material Design znajdziesz w dokumentacji Material Design 3.
Najważniejsze
Bottom Navigation — wzorzec nawigacji, w którym główne sekcje aplikacji są dostępne przez panel w dolnej części ekranu. Ten wzorzec stał się standardem projektowania mobilnego dzięki wygodzie obsługi jedną ręką. W przeciwieństwie do menu bocznego (Drawer), Bottom Navigation jest zawsze widoczna i nie wymaga dodatkowych gestów do otwarcia.
Material Design 3 (2026) definiuje Navigation Bar jako komponent z trzema stanami: default (ikona + podpis), labeled (powiększony podpis, aktywna jedna zakładka) i unlabeled (tylko ikony). Google zaleca Navigation Bar dla aplikacji z 3–5 równorzędnymi sekcjami. Dla 6+ sekcji — Navigation Drawer. W iOS SwiftUI TabView automatycznie używa dolnego panelu z systemowym stylem.
Badanie UX Movement (2025) wykazało: Bottom Navigation skraca czas wykonywania zadań o 27% w porównaniu z wysuwanym menu, ponieważ użytkownik widzi wszystkie dostępne sekcje bez dodatkowych działań. Liczba błędnych kliknięć spada o 34% dzięki dużym celom dotyku (minimum 48x48 dp w Android, 44x44 pt w iOS).
BottomNavigationView w Android — komponent z Material 3 Library (com.google.android.material.navigation.NavigationBarView). Zastąpił on przestarzały BottomNavigationView z Material 2 i dodał obsługę dynamicznych kolorów Material You, animowanego wskaźnika aktywnej zakładki oraz wbudowanych znaczników. Komponent konfiguruje się przez XML-menu i jest w pełni zgodny z Navigation Component.
// Aktywność z BottomNavigationView i NavHostFragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView = findViewById<NavigationBarView>(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Automatyczna synchronizacja nawigacji
navView.setupWithNavController(navController)
// Konfiguracja znacznika
val badge = navView.getOrCreateBadge(R.id.navigation_messages)
badge.number = 8
badge.badgeGravity = BadgeDrawable.TOP_END
}
}
// Menu XML dla Bottom Navigation (res/menu/bottom_nav_menu.xml)
// <?xml version="1.0" encoding="utf-8"?>
// <menu xmlns:android="http://schemas.android.com/apk/res/android">
// <item android:id="@+id/navigation_home"
// android:icon="@drawable/ic_home"
// android:title="Główna" />
// <item android:id="@+id/navigation_messages"
// android:icon="@drawable/ic_chat"
// android:title="Czaty" />
// <item android:id="@+id/navigation_profile"
// android:icon="@drawable/ic_person"
// android:title="Profil" />
// </menu>Material 3 NavigationBarView obsługuje trzy tryby labelVisibilityMode: LABEL_VISIBILITY_AUTO (domyślnie — podpis wyświetlany dla aktywnej zakładki), LABEL_VISIBILITY_LABELED (podpisy przy wszystkich), LABEL_VISIBILITY_UNLABELED (tylko ikony). Animowany wskaźnik aktywnej zakładki konfiguruje się przez itemActiveIndicatorStyle z niestandardowym efektem ripple.
TabView — wbudowany kontener SwiftUI do tworzenia nawigacji dolnej. Każda zakładka jest definiowana przez modyfikator .tabItem z ikoną i tekstem. TabView automatycznie tworzy UITabBarController pod maską i obsługuje wszystkie funkcje natywnego panelu: znaczniki, kolor znaczników, animację przełączania i adaptację do Dynamic Type.
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
HomeView()
.tabItem {
Label("Główna", systemImage: "house.fill")
}
.badge(3)
SearchView()
.tabItem {
Label("Szukaj", systemImage: "magnifyingglass")
}
NotificationsView()
.tabItem {
Label("Powiadomienia", systemImage: "bell.fill")
}
.badge("12")
ProfileView()
.tabItem {
Label("Profil", systemImage: "person.circle.fill")
}
}
}
}TabView obsługuje modyfikator .badge (iOS 15+), który przyjmuje Int (znacznik liczbowy) lub String (tekstowy). Kolor znacznika można zmienić przez .badgeProminence(.increased) — sprawia, że znacznik jest jaśniejszy. Animacja przełączania zakładek konfiguruje się przez .tabViewStyle(.automatic) lub niestandardowe style. Do kontroli programowego przełączania używa się @State z selection.
Bottom Navigation rzadko jest używana samodzielnie — każda zakładka zwykle zawiera nawigator stosowy (NavigationView/NavigationStack w SwiftUI, NavHostFragment w Android). Taka kombinacja daje użytkownikowi zarówno szybki dostęp do sekcji (Tab), jak i głęboką nawigację wewnątrz każdej sekcji (Stack). Jest to standardowa architektura dla aplikacji produkcyjnych.
struct AppTabView: View {
var body: some View {
TabView {
NavigationStack {
HomeView()
}
.tabItem {
Label("Główna", systemImage: "house")
}
NavigationStack {
SearchView()
}
.tabItem {
Label("Szukaj", systemImage: "magnifyingglass")
}
}
}
}
// Wewnątrz HomeView — nawigacja stosowa
struct HomeView: View {
var body: some View {
List(items) { item in
NavigationLink("\(item.title)", value: item)
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
}W Android ta sama kombinacja jest implementowana przez NavHostFragment dla każdej zakładki. Navigation Component automatyzuje tworzenie back stack dla każdej zakładki: przy przełączaniu zakładek stan stosu jest zachowywany, przy powrocie — przywracany. Zapewnia to płynne UX, jak w systemowych aplikacjach Google (Play Market, YouTube).
Material 3 (Material You) wprowadza kluczową zmianę w Bottom Navigation — dynamiczne kolory generowane z tapety użytkownika. System wyodrębnia dominujące kolory z wallpaper i tworzy paletę z 5 kluczowymi tonami. NavigationBarView automatycznie stosuje te kolory: aktywna zakładka otrzymuje kolor primary, nieaktywne — onSurface variant.
Animacja wskaźnika aktywnej zakładki stała się płynna: przy przełączaniu wskaźnik animacyjnie przesuwa się do nowej zakładki z interpolacją. Efekt ripple przy dotyku używa koloru secondary. Bottom Navigation w Material 3 obsługuje również niestandardowe animacje przez itemActiveIndicatorStyle — programista może ustawić kształt (owal, prostokąt), marginesy i kolor wskaźnika.
<!-- Styl aktywnego wskaźnika NavigationBarView -->
<style name="Widget.MyApp.NavigationBarView.ActiveIndicator"
parent="Widget.Material3.NavigationBarView.ActiveIndicator">
<item name="android:height">32dp</item>
<item name="android:width">64dp</item>
<item name="android:marginHorizontal">8dp</item>
<item name="shapeAppearance">
@style/ShapeAppearance.Material3.Corner.Full
</item>
<item name="color">@color/primary_container</item>
</style>Przy projektowaniu Bottom Navigation należy uwzględniać badania użyteczności. NN Group (2026): dolny panel powinien mieć wysokość minimum 56 dp, cele dotyku — nie mniej niż 48 dp. Tekst etykiet — maksymalnie 12 znaków (łacinka) lub 8 znaków (cyrylica). Aktywna zakładka powinna różnić się nie tylko kolorem, ale także stanem ikony (filled vs outlined).
Material Design 3 zaleca następujące wzorce: 4 zakładki — optymalnie do spokojnego skanowania; ikona „+” na środku (FloatingActionButton) — dla głównej akcji; znaczniki — tylko dla liczników działań użytkownika. Nie należy: używać Bottom Navigation z 2 zakładkami (lepiej Tab Layout), zmieniać kolejności zakładek dynamicznie, ukrywać panelu na zagnieżdżonych ekranach.
Często zadawane pytania
Bottom Navigation — panel na dole ekranu, zawsze widoczny, dla 3–5 równorzędnych sekcji. Navigation Drawer — menu boczne, wywoływane gestem lub przyciskiem, dla 6+ sekcji, ustawień i stron drugorzędnych. Drawer ukrywa treść, Bottom Navigation — nie.
4 zakładki — optymalna liczba według danych NN Group. 3 — minimalna dla uzasadnienia dolnego panelu. 5 — maksymalna, przy której wszystkie zakładki pozostają rozróżnialne. 6+ wymaga przejścia na Navigation Drawer lub pozycję „Więcej” w iOS.
W Android Material 3 użyj getOrCreateBadge(itemId) na NavigationBarView. Ustaw liczbę przez badge.number i pozycję przez badgeGravity (TOP_END, TOP_START). W iOS SwiftUI — modyfikator .badge(Int) na .tabItem. W UIKit — tabBarItem.badgeValue = "N".
Tak. Material 3 NavigationBarView animuje przesuwanie wskaźnika aktywnej zakładki. SwiftUI TabView używa systemowej animacji iOS. Do niestandardowych animacji treści użyj matchedGeometryEffect (SwiftUI) lub Transition (Jetpack Compose). Animacja samego panelu przełączania — systemowa.
Tak, dla mobile-first i PWA. Material Design 3 ma webowy komponent Navigation Bar. Jednak na desktopie lepiej użyć panelu bocznego (Side Navigation) — poziome miejsce pozwala pokazać więcej punktów. Bottom Navigation na desktopie to antypattern.
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ż