BottomNavigation: bu nədir, strukturu və Jetpack Compose-da qurulumu

Müəllif: IT Sectr Dərc olunub: 2026-06-29 Oxuma vaxtı: 8 dəq

BottomNavigation (Material3-də NavigationBar) — tətbiqin üç-beş əsas ekranı arasında naviqasiyanı təmin edən Material Design komponentidir. Jetpack Compose-da aşağı panel NavigationBar və ya BottomNavigation vasitəsilə həyata keçirilir, burada hər bir element ikon və mətn etiketi ilə təmsil olunur. Google Material Design (2025) məlumatlarına görə, BottomNavigation iOS və Android üçün əsas naviqasiya nümunəsi kimi tövsiyə olunur. Panel avtomatik olaraq WindowInsets vasitəsilə sistem naviqasiyasının (Gesture Navigation) hündürlüyünə uyğunlaşır. Material3-də NavigationBar dynamic color, badge və adaptiv boşluqları dəstəkləyir.

Əsas məqamlar

  • BottomNavigation — Material3-də NavigationBar vasitəsilə həyata keçirilən 3–5 ekran üçün aşağı naviqasiya paneli
  • NavigationBarItem — ikon, etiket və bildirişlər üçün badge ehtiva edən panel elementi
  • NavHost ilə əlaqə — element seçimi qrafı dəyişmək üçün NavController-da navigate() işə salır
  • Material3 Dynamic Color və WindowInsets vasitəsilə sistem naviqasiyasının avtomatik nəzərə alınmasını əlavə edir
  • Badge — ikonda bildiriş nişanı, BadgedBox vasitəsilə sayla həyata keçirilir

Jetpack Compose-da BottomNavigation nədir?

BottomNavigation — üçdən beşə qədər menyu bəndini göstərən aşağı naviqasiya paneli üçün Material Design komponentidir. Jetpack Compose-da BottomNavigation (Material2) və NavigationBar (Material3) composable funksiyaları vasitəsilə həyata keçirilir. Panel ekranın aşağı hissəsində yerləşir və tətbiqin əsas bölmələrinə sürətli girişi təmin edir.

BottomNavigation-ın əsas vəzifəsi ekran səviyyələri arasında əsas naviqasiyanı təşkil etməkdir. Panelin hər bir elementi ayrıca ekranı təmsil edir (Home, Search, Profile). Sıxma əsas ekran sahəsində məzmunu dəyişir. BottomNavigation iç-içə naviqasiya üçün nəzərdə tutulmayıb — bunun üçün yuxarı hissədə vərəqlər (Tabs) istifadə olunur.

Material Design Guidelines (2025) məlumatlarına görə, aşağı panel yalnız tətbiqin istənilən yerindən əlçatan olan bölmələri ehtiva etməlidir. Panelin uşaq ekranlarda (məsələn, təfərrüatlı səhifə açarkən) gizlədilməsi standart təcrübədir. Compose-da BottomNavigation görünürlüyü Scaffold vəziyyəti və ya NavController cari marşrutu əsasında şərti render vasitəsilə idarə olunur.

Material3-də Legacy BottomNavigation əvəzinə NavigationBar istifadə etmək tövsiyə olunur. NavigationBar Dynamic Color, WindowInsets dəstəyi və təkmilləşdirilmiş sıxma animasiyasını ehtiva edir. Google-a görə, NavigationBar perspektivli komponentdir, M2-dən BottomNavigation isə yalnız geriyə uyğunluq üçün qalır.

Hər bir NavigationBar elementi NavigationBarItem composable vasitəsilə həyata keçirilir. Elementin parametrləri: icon (ikon), label (mətn etiketi), selected (seçim vəziyyəti) və onClick (geriyə çağırış). NavigationBarItem avtomatik olaraq seçilmiş rəngi (primary) və aktivləşdirmə zamanı ikon ölçüsünün dəyişmə animasiyasını tətbiq edir.

kotlin
@Composable
fun BottomNavBar() {
    val items = listOf(
        Screen.Home,
        Screen.Search,
        Screen.Profile
    )
    var selectedItem by remember { mutableIntStateOf(0) }
    NavigationBar {
        items.forEachIndexed { index, item ->
            NavigationBarItem(
                icon = { Icon(item.icon, contentDescription = item.label) },
                label = { Text(item.label) },
                selected = selectedItem == index,
                onClick = { selectedItem = index }
            )
        }
    }
}

NavigationBarItem üçün ikonlar seçilmiş vəziyyət üçün Filled, seçilməmiş üçün Outlined olmalıdır. Material Icons hər iki dəsti təqdim edir: Icons.Filled.Home və Icons.Outlined.Home. NavigationBarItem susmaya görə selected üçün filled variantını göstərir. Fərqli göstəriş lazımdırsa, ikonu şərti olaraq ötürün: if (selected) Filled.X else Outlined.X.

Elementin mətn etiketinin uzunluğu — 12 simvoldan (latın əlifbası) və ya 8 simvoldan (kiril əlifbası) çox olmamalıdır. Uzun etiketlər üç nöqtə ilə kəsilir. Etiketlər üçün maxLines = 1 və ellipsis = TextTruncation.Ellipsis istifadə edin. Etiket həmişə tələb olunarsa, alwaysShowLabel = true parametrini qoyun (susmaya görə true).

ParametrTipTəsvir
icon@Composable () -> UnitPanel elementinin ikonu
label@Composable (() -> Unit)?Ikon altında mətn etiketi
selectedBooleanSeçilmiş element bayrağı
onClick() -> UnitSıxma zamanı geriyə çağırış
badge@Composable (() -> Unit)?Bildiriş sayı ilə badge

BottomNavigation-ın NavHost ilə əlaqəsi

selectedItem-in birbaşa yenilənməsi naviqasiyanı yönləndirmir — ekranları dəyişmək üçün NavController ilə inteqrasiya lazımdır. Tipik nümunə: NavigationBarItem-də onClick navController.navigate(route) çağırır, selectedItem isə NavController-ın cari marşrutundan müəyyən edilir.

NavController cari back stack-i saxlayır. Panelin hansı elementinin seçildiyini müəyyən etmək üçün cari marşrutu (navController.currentBackStackEntryAsState().value?.destination?.route) elementlərin marşrutları ilə müqayisə edin. Marşrut uyğun gələrsə — element seçilmiş sayılır. Bu vəziyyətin təkrarlanmasını aradan qaldırır.

kotlin
@Composable
fun MainScreen(navController: NavController) {
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route
    Scaffold(
        bottomBar = {
            NavigationBar {
                items.forEach { item ->
                    NavigationBarItem(
                        icon = { Icon(item.icon, contentDescription = item.label) },
                        label = { Text(item.label) },
                        selected = currentRoute == item.route,
                        onClick = {
                            navController.navigate(item.route) {
                                popUpTo(navController.graph.findStartDestination().id) {
                                    saveState = true
                                }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                }
            }
        }
    ) { /* content */ }
}

navigate() daxilində əsas parametrlər: popUpTo(startDestination) vərəqləri dəyişərkən back stack-in yığılmasının qarşısını alır, launchSingleTop marşrutun yığında təkrarlanmasını istisna edir, restoreState isə vərəqə əvvəlki ziyarətin vəziyyətini bərpa edir. Bu parametrlər olmadan hər sıxma yığında yeni giriş yaradır ki, bu da Geri düyməsinin düzgün işləməməsinə səbəb olur.

Material3-də NavigationBar: Dynamic Color və adaptasiya

Material3 (M3) NavigationBarNavigationBarItem-i Material2-dən BottomNavigation-ın əvəzi kimi təqdim edir. M3-ün əsas üstünlükləri: Dynamic Color, adaptiv hündürlük, elementin tam eni boyunca ripple animasiyası və sistem naviqasiyasını nəzərə almaq üçün WindowInsets dəstəyi.

Dynamic Color avtomatik olaraq NavigationBar rənglərini cihazın divar kağızı əsasında seçir (Android 12+). Aktiv element primary rənginə, qeyri-aktivlər isə onSurfaceVariant rənginə boyanır. NavigationBar susmaya görə Modifier.navigationBarsPadding() vasitəsilə sistem naviqasiyasının üzərinə qalxır. Əl ilə idarə etmək üçün windowInsets parametrindən istifadə edin.

M3-də NavigationBar avtomatik olaraq aktiv elementin enini animasiya edir — ikon sola sürüşür, etiket genişlənir. Animasiya 300 ms davam edir və standart Compose easing istifadə edir. Bu davranış arzuolunmazdırsa, NavigationBarItem-də alwaysShowLabel = true vasitəsilə etiketi həmişə göstərin.

NavigationBar rənglərinin fərdiləşdirilməsi

Rəngləri dəyişdirmək üçün colors parametrində NavigationBarColors ötürün. Susmaya görə NavigationBarDefaults.colors() istifadə olunur, lakin öz rənglərinizi təyin edə bilərsiniz: containerColor (panel fonu), contentColor (ikon rəngi), indicatorColor (aktiv element fonu). M2-də rənglərin BottomNavigationDefaults vasitəsilə təyin edildiyindən fərqli olaraq, M3-də vahid NavColors interfeysi istifadə olunur.

Layihədə M2-dən (androidx.compose.material) BottomNavigation istifadə olunursa, Google M3 NavigationBar-a miqrasiyanı tövsiyə edir. Miqrasiya importların dəyişdirilməsi, parametrlərin yenilənməsi və @OptIn(ExperimentalMaterial3Api::class) əlavə edilməsini əhatə edir. M2-dən BottomNavigation köhnəlmiş hesab olunur və yeni funksiyalar almır.

NavigationBar vəziyyəti cari seçilmiş elementin indeksini saxlayır. Sadə hallarda remember { mutableIntStateOf(0) } istifadə olunur. Lakin istehsal tətbiqləri üçün indeks naviqasiya qrafı ilə sinxronlaşdırılmalıdır, UI-nin lokal vəziyyəti olmamalıdır.

Vəziyyətin idarə edilməsinə əsas yanaşmalar: NavController-based (tövsiyə olunan) və ViewModel-based. Birinci halda selectedItem NavController-ın cari marşrutundan hesablanır. İkinci halda — ViewModel cari ekranı saxlayır, NavigationBarItem isə ViewModel-dən StateFlow oxuyur. NavController-based daha sadədir, ViewModel-based mürəkkəb logikada (avtorizasiya, A/B testləri) daha çox nəzarət verir.

saveState və restoreState istifadə edərkən NavController avtomatik olaraq hər vərəq daxilində LazyColumn və digər komponentlərin vəziyyətini saxlayır və bərpa edir. Bu, scroll mövqeyini saxlamaq üçün ViewModel-ə ehtiyacı aradan qaldırır. Lakin saxlama giriş sahələri üçün tətbiq olunmur — onlar SavedStateHandle və ya ViewModel tələb edir.

Elementlərdə bildiriş nişanları və sayğaclar

Badge — NavigationBarItem ikonunda göstərilən yığcam bildiriş göstəricisidir. Material3-də badge BadgedBox vasitəsilə həyata keçirilir, o ikonu əhatə edir və badge-i yuxarı sağ küncə yerləşdirir. Badge say (bildirişlərin sayı) və ya nöqtə (sadəcə mövcudluq göstəricisi) ehtiva edə bilər.

kotlin
@Composable
fun HomeItem(unreadCount: Int) {
    NavigationBarItem(
        icon = {
            BadgedBox(badge = {
                if (unreadCount > 0) {
                    Badge { Text(unreadCount.toString()) }
                }
            }) {
                Icon(Icons.Filled.Home, contentDescription = "Ana səhifə")
            }
        },
        label = { Text("Home") },
        selected = false,
        onClick = { }
    )
}

BadgedBox avtomatik olaraq Badge-i uşaq elementin yuxarı sağ küncünə yerləşdirir. Say 99-u keçərsə, Badge “99+” göstərir. Sıfır dəyərində badge-i gizlətmək üçün if (count > 0) şərtindən istifadə edin. Material3-dən Badge susmaya görə error rənginə (qırmızı) və ağ mətnə malikdir. Fərdiləşdirmə BadgeDefaults.colors(containerColor, contentColor) vasitəsilə aparılır.

Material2-də badge mövcud deyildi — onu Canvas vasitəsilə əl ilə çəkmək və ya üçüncü tərəf kitabxanalarından istifadə etmək lazım idi. Material3 bu problemi yerli komponentlə həll etdi. Android Developers (2025) məlumatlarına görə, BadgedBox NavigationBar ilə tətbiqlərin 40%-də istifadə olunur, bunun 60%-i oxunmamış mesajları göstərmək üçündür.

Tez-tez verilən suallar

BottomNavigation-da neçə element olmalıdır?

Material Design 3-dən 5 elementə qədər tövsiyə edir. Üçdən az — məqsədəuyğun deyil (Tabs istifadə etmək daha yaxşıdır). Beşdən çox — etiketlərin oxunaqlılığını pisləşdirir və touch-targeti azaldır. 5-dən çox bölmə tələb olunarsa, Navigation Rail (planşetlər) və ya Drawer istifadə edin.

Uşaq ekranlarda BottomNavigation-ı necə gizlətmək olar?

Panelin göründüyü marşrutların siyahısını müəyyən edin (adətən kök marşrutlar). Scaffold bottomBar-da NavigationBar-ı yalnız currentRoute bottomNavRoutes daxilində olduqda ötürün. Alternativ — bottomBar olmadan iç-içə ekranlar üçün ayrıca qrafla NavHost.

NavigationBar (M3) və BottomNavigation (M2) arasında nə fərq var?

Material3-dən NavigationBar Dynamic Color, BadgedBox, WindowInsets və aktiv elementin animasiyalı enini dəstəkləyir. Material2-dən BottomNavigation bu funksiyaları olmayan köhnə API-dir. Google yeni layihələr üçün NavigationBar istifadə etməyi və mövcud layihələri miqrasiya etməyi tövsiyə edir.

Niyə BottomNavigation elementinə sıxdıqda ekran yenidən yaradılır?

Problem navigate()-də saveStaterestoreState-in olmamasıdır. Onlar olmadan NavController əvvəlki vərəqin vəziyyətini saxlamır. LazyColumn, scroll və giriş sahələrini qorumaq üçün NavOptions-da popUpTo(startDestination) { saveState = true } və restoreState = true əlavə edin.

Vərəqlər arasında keçid animasiyasını necə fərdiləşdirmək olar?

Keçid animasiyası BottomNavigation deyil, NavHost səviyyəsində idarə olunur. Xüsusi animasiyalarla composable(route, enterTransition, exitTransition) əlavə edin. BottomNavigation üçün fading animasiyası (fadeIn + fadeOut) 300ms müddəti ilə tipikdir.

Nəticə

  • BottomNavigation (M3-də NavigationBar) — tətbiqin 3–5 əsas ekranı arasında keçid üçün aşağı panel
  • NavigationBarItem — ikon, etiket, badge və seçim vəziyyəti olan panel elementi
  • NavController ilə inteqrasiya yığının düzgün idarə edilməsi üçün popUpTo, launchSingleTop və restoreState tələb edir
  • Material3 NavigationBar Dynamic Color, BadgedBox, WindowInsets və aktiv element animasiyasını dəstəkləyir
  • BadgedBox — element ikonunda say və ya nöqtə ilə bildiriş nişanları üçün komponent
  • Seçim vəziyyəti NavController ilə sinxronizasiya üçün currentBackStackEntryAsState-dən hesablanır
  • Paneli uşaq ekranlarda gizlətmək üçün Scaffold bottomBar-da marşrut siyahısı əsasında şərti renderdən istifadə edin

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun