BottomNavigation (Material3 da NavigationBar) — ilovaning uch-besh asosiy ekrani o'rtasida navigatsiyani ta'minlovchi Material Design komponenti. Jetpack Compose da pastki panel NavigationBar yoki BottomNavigation orqali amalga oshiriladi, bunda har bir element ikonka va matn yorlig'i bilan ifodalanadi. Google Material Design (2025) ma'lumotlariga ko'ra, BottomNavigation iOS va Android uchun asosiy navigatsiya namunasi sifatida tavsiya etiladi. Panel avtomatik ravishda WindowInsets orqali tizim navigatsiyasi (Gesture Navigation) balandligiga moslashadi. Material3 da NavigationBar dynamic color, badge va adaptiv bo'shliqlarni qo'llab-quvvatlaydi.
Asosiy fikrlar
BottomNavigation — uchdan beshgacha menyu bandini ko'rsatadigan pastki navigatsiya paneli uchun Material Design komponenti. Jetpack Compose da BottomNavigation (Material2) va NavigationBar (Material3) composable funksiyalari orqali amalga oshiriladi. Panel ekranning pastki qismida joylashadi va ilovaning asosiy bo'limlariga tezkor kirishni ta'minlaydi.
BottomNavigation ning asosiy vazifasi ekran darajalari o'rtasida asosiy navigatsiyani tashkil qilishdir. Panelning har bir elementi alohida ekranni (Home, Search, Profile) ifodalaydi. Bosish asosiy ekran maydonidagi tarkibni almashtiradi. BottomNavigation ichki navigatsiya uchun mo'ljallanmagan — buning uchun yuqori qismdagi varaqlar (Tabs) ishlatiladi.
Material Design Guidelines (2025) ma'lumotlariga ko'ra, pastki panel faqat ilovaning istalgan nuqtasidan mavjud bo'lgan bo'limlarni o'z ichiga olishi kerak. Panelni qo'shimcha ekranlarda (masalan, batafsil sahifani ochishda) yashirish standart amaliyotdir. Compose da BottomNavigation ko'rinishi Scaffold holati yoki NavController joriy marshruti asosida shartli renderlash orqali boshqariladi.
Material3 da Legacy BottomNavigation o'rniga NavigationBar dan foydalanish tavsiya etiladi. NavigationBar Dynamic Color, WindowInsets qo'llab-quvvatlashi va yaxshilangan bosish animatsiyasini o'z ichiga oladi. Google ga ko'ra, NavigationBar istiqbolli komponent, M2 dan BottomNavigation esa faqat orqaga moslik uchun qoladi.
Har bir NavigationBar elementi NavigationBarItem composable orqali amalga oshiriladi. Element parametrlari: icon (ikonka), label (matn yorlig'i), selected (tanlash holati) va onClick (qayta chaqiruv). NavigationBarItem avtomatik ravishda tanlangan rangni (primary) va faollashtirishda ikonka o'lchamining o'zgarish animatsiyasini qo'llaydi.
@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 uchun ikonkalar tanlangan holat uchun Filled va tanlanmagan holat uchun Outlined bo'lishi kerak. Material Icons ikkala to'plamni taqdim etadi: Icons.Filled.Home va Icons.Outlined.Home. Sukut bo'yicha NavigationBarItem selected uchun filled variantini ko'rsatadi. Agar turli ko'rinish kerak bo'lsa, ikonkani shartli ravishda uzating: if (selected) Filled.X else Outlined.X.
Element matn yorlig'ining uzunligi — 12 belgidan (lotin alifbosi) yoki 8 belgidan (kirill alifbosi) oshmasligi kerak. Uzun yorliqlar uch nuqta bilan kesiladi. Yorliqlar uchun maxLines = 1 va ellipsis = TextTruncation.Ellipsis dan foydalaning. Agar yorliq har doim kerak bo'lsa, alwaysShowLabel = true parametrini o'rnating (sukut bo'yicha true).
| Parametr | Tur | Tavsif |
|---|---|---|
| icon | @Composable () -> Unit | Panel elementi ikonkasi |
| label | @Composable (() -> Unit)? | Ikonka ostidagi matn yorlig'i |
| selected | Boolean | Tanlangan element bayrog'i |
| onClick | () -> Unit | Bosishdagi qayta chaqiruv |
| badge | @Composable (() -> Unit)? | Bildirishnomalar soni bilan badge |
selectedItem ni to'g'ridan-to'g'ri yangilash navigatsiyani yo'naltirmaydi — ekranlarni almashtirish uchun NavController bilan integratsiya kerak. Odatdagi namuna: NavigationBarItem dagi onClick navController.navigate(route) ni chaqiradi, selectedItem esa NavController ning joriy marshrutidan aniqlanadi.
NavController joriy back stack ni saqlaydi. Panelning qaysi elementi tanlanganligini aniqlash uchun joriy marshrutni (navController.currentBackStackEntryAsState().value?.destination?.route) elementlarning marshrutlari bilan solishtiring. Agar marshrut mos kelsa — element tanlangan hisoblanadi. Bu holatning takrorlanishini oldini oladi.
@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() dagi asosiy sozlamalar: popUpTo(startDestination) varaqlarni almashtirishda back stack to'planishining oldini oladi, launchSingleTop marshrutning stekda takrorlanishini istisno qiladi, restoreState esa varaqga oldingi tashrif holatini tiklaydi. Bu parametrlarsiz har bir bosish stekda yangi yozuv yaratadi, bu esa Orqaga tugmasining noto'g'ri ishlashiga olib keladi.
Material3 (M3) NavigationBar va NavigationBarItem ni Material2 dagi BottomNavigation o'rnini bosuvchi sifatida taqdim etadi. M3 ning asosiy afzalliklari: Dynamic Color, adaptiv balandlik, elementning butun kengligi bo'ylab ripple animatsiyasi va tizim navigatsiyasini hisobga olish uchun WindowInsets qo'llab-quvvatlashi.
Dynamic Color avtomatik ravishda NavigationBar ranglarini qurilma fon rasmi asosida tanlaydi (Android 12+). Faol element primary rangiga, nofaollar esa onSurfaceVariant rangiga bo'yaladi. Sukut bo'yicha NavigationBar Modifier.navigationBarsPadding() orqali tizim navigatsiyasidan yuqoriga ko'tariladi. Qo'lda boshqarish uchun windowInsets parametridan foydalaning.
M3 da NavigationBar avtomatik ravishda faol elementning kengligini animatsiya qiladi — ikonka chapga siljiydi, yorliq kengayadi. Animatsiya 300 ms davom etadi va standart Compose easing dan foydalanadi. Agar bu xatti-harakat istalmagan bo'lsa, NavigationBarItem da alwaysShowLabel = true orqali yorliqni doim ko'rsating.
Ranglarni o'zgartirish uchun colors parametrida NavigationBarColors ni uzating. Sukut bo'yicha NavigationBarDefaults.colors() ishlatiladi, lekin o'z ranglaringizni o'rnatishingiz mumkin: containerColor (panel foni), contentColor (ikonka rangi), indicatorColor (faol element foni). M2 da ranglar BottomNavigationDefaults orqali o'rnatilganidan farqli o'laroq, M3 da yagona NavColors interfeysi ishlatiladi.
Agar loyihada M2 dan (androidx.compose.material) BottomNavigation ishlatilsa, Google M3 NavigationBar ga migratsiyani tavsiya qiladi. Migratsiya importlarni almashtirish, parametrlarni yangilash va @OptIn(ExperimentalMaterial3Api::class) qo'shishni o'z ichiga oladi. M2 dan BottomNavigation eskirgan hisoblanadi va yangi funksiyalarni olmaydi.
NavigationBar holati joriy tanlangan elementning indeksini saqlaydi. Oddiy hollarda remember { mutableIntStateOf(0) } ishlatiladi. Biroq, ishlab chiqarish ilovalari uchun indeks navigatsiya grafigi bilan sinxronlashtirilishi kerak, UI ning lokal holati bo'lmasligi kerak.
Holatni boshqarishning asosiy yondashuvlari: NavController-based (tavsiya etiladi) va ViewModel-based. Birinchi holatda selectedItem NavController ning joriy marshrutidan hisoblanadi. Ikkinchi holatda — ViewModel joriy ekranni saqlaydi, NavigationBarItem esa ViewModel dan StateFlow ni o'qiydi. NavController-based soddaroq, ViewModel-based murakkab logikada (avtorizatsiya, A/B testlari) ko'proq nazorat beradi.
saveState va restoreState dan foydalanganda NavController avtomatik ravishda har bir varaq ichidagi LazyColumn va boshqa komponentlarning holatini saqlaydi va tiklaydi. Bu scroll pozitsiyasini saqlash uchun ViewModel ga ehtiyojni yo'q qiladi. Biroq, saqlash kiritish maydonlari uchun qo'llanilmaydi — ular SavedStateHandle yoki ViewModel talab qiladi.
Badge — NavigationBarItem ikonkasida ko'rsatiladigan ixcham bildirishnoma ko'rsatkichidir. Material3 da badge BadgedBox orqali amalga oshiriladi, u ikonkani o'rab oladi va badgeni yuqori o'ng burchakka joylashtiradi. Badge son (bildirishnomalar miqdori) yoki nuqta (mavjudlik ko'rsatkichi) ni o'z ichiga olishi mumkin.
@Composable
fun HomeItem(unreadCount: Int) {
NavigationBarItem(
icon = {
BadgedBox(badge = {
if (unreadCount > 0) {
Badge { Text(unreadCount.toString()) }
}
}) {
Icon(Icons.Filled.Home, contentDescription = "Bosh sahifa")
}
},
label = { Text("Home") },
selected = false,
onClick = { }
)
}
BadgedBox avtomatik ravishda Badge ni qo'shimcha elementning yuqori o'ng burchagiga joylashtiradi. Agar son 99 dan oshsa, Badge “99+” ni ko'rsatadi. Nol qiymatida badgeni yashirish uchun if (count > 0) shartidan foydalaning. Material3 dan Badge sukut bo'yicha error rangi (qizil) va oq matnga ega. Sozlash BadgeDefaults.colors(containerColor, contentColor) orqali amalga oshiriladi.
Material2 da badge mavjud emas edi — uni Canvas orqali qo'lda chizish yoki uchinchi tomon kutubxonalaridan foydalanish kerak edi. Material3 bu muammoni mahalliy komponent bilan hal qildi. Android Developers (2025) ma'lumotlariga ko'ra, BadgedBox NavigationBar bilan ilovalarning 40 foizida ishlatiladi, shundan 60 foizi o'qilmagan xabarlarni ko'rsatish uchun.
Tez-tez beriladigan savollar
Material Design 3 dan 5 gacha elementni tavsiya qiladi. Uchdan kam — maqsadga muvofiq emas (Tabs ishlatish yaxshiroq). Beshdan ko'p — yorliqlarning o'qilishini yomonlashtiradi va touch-target ni kamaytiradi. Agar 5 dan ortiq bo'lim kerak bo'lsa, Navigation Rail (planshetlar) yoki Drawer dan foydalaning.
Panel ko'rinadigan marshrutlar ro'yxatini aniqlang (odatda ildiz marshrutlar). Scaffold bottomBar da NavigationBar ni faqat currentRoute bottomNavRoutes ichida bo'lganda uzating. Muqobil — bottomBar siz ichki ekranlar uchun alohida grafik bilan NavHost.
Material3 dan NavigationBar Dynamic Color, BadgedBox, WindowInsets va faol elementning animatsiyalangan kengligini qo'llab-quvvatlaydi. Material2 dan BottomNavigation bu funksiyalarsiz eski API dir. Google yangi loyihalar uchun NavigationBar dan foydalanishni va mavjud loyihalarni migratsiya qilishni tavsiya qiladi.
Muammo navigate() da saveState va restoreState ning yo'qligidir. Ularsiz NavController oldingi varaqning holatini saqlamaydi. LazyColumn, scroll va kiritish maydonlarini saqlash uchun NavOptions da popUpTo(startDestination) { saveState = true } va restoreState = true qo'shing.
Almashtirish animatsiyasi BottomNavigation emas, NavHost darajasida boshqariladi. Maxsus animatsiyalar bilan composable(route, enterTransition, exitTransition) qo'shing. BottomNavigation uchun fading animatsiyasi (fadeIn + fadeOut) 300 ms davomiylik bilan odatiydir.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.