NavController Navigation Compose kutubxonasining markaziy komponenti bo‘lib, Android ilovalarida navigatsiya steki va back stack holatini boshqaradi. NavController orqali ekranlar o‘rtasida o‘tishlar, oldingi sahifalarga qaytish va marshrutlar o‘rtasida ma’lumot uzatish amalga oshiriladi. Android Developers (2025) ma’lumotlariga ko‘ra, NavController bir nechta ekranga ega har qanday Compose ilovasining majburiy elementidir. Kontroller rememberNavController() orqali yaratiladi, NavHost-ga uzatiladi va kompozitsiyaning istalgan nuqtasidan navigate() chaqiruvi uchun mavjud. O‘rnatilgan SavedStateHandle qo‘llab-quvvatlashi rekonfiguratsiya vaqtida ViewModel holatini avtomatik saqlaydi.
Asosiy fikrlar
NavController — Navigation Compose kutubxonasidan olingan sinf bo‘lib, Compose ilovalari uchun navigatsiya kontrollerini amalga oshiradi. NavController NavBackStackEntry stekini boshqaradi, bu erda har bir yozuv marshrut, argumentlar va ekran holatini o‘z ichiga oladi. Kontroller asosiy navigatsiya operatsiyalarini qo‘llab-quvvatlaydi: o‘tish, qaytish, almashtirish va tozalash.
Navgiatsiya FragmentManager yoki Intent orqali amalga oshirilgan View tizimidan farqli o‘laroq, NavController faqat Compose kontekstida ishlaydi. Back stack Fragment steki emas, balki NavDestination grafi shaklida saqlanadi. Bu Fragment yaratish va yo‘q qilish overheadini bartaraf etadi, shuningdek testlashni soddalashtiradi — NavController TestNavHostController orqali mock qilinishi mumkin.
NavController NavHost bilan chambarchas bog‘liq — grafdan joriy ekranni render qiluvchi konteyner. NavHost bo‘lmasa, NavController composable funksiyalarini ko‘rsata olmaydi, lekin stekni boshqarish qobiliyatini saqlab qoladi. Odatdagi arxitekturada NavController Activity yoki asosiy composable darajasida yaratiladi va parametrlar orqali kompozitsiya daraxti bo‘ylab pastga uzatiladi.
Google ma’lumotlariga ko‘ra, NavController bir nechta major relizlardan o‘tgan. 2.8.0 versiyasi Type-Safe Navigation-ni qo‘shdi, 2.9.0 versiyasi — predictive back gesture (Android 14+) qo‘llab-quvvatlashini. Kontroller Material3 Scaffold va BottomNavigation bilan mos keladi. Multimodul loyihalar uchun NavController DI (Hilt/Koin) yoki konstruktor parametrlari orqali uzatiladi.
NavController rememberNavController() composable funksiyasi orqali yaratiladi. Funksiya joriy composable-ning hayotiy sikliga bog‘langan NavHostController (NavController vorisi) namunasini qaytaradi. Kompozitsiyadan chiqishda kontroller tozalanadi. Rekonfiguratsiya vaqtida kontrollerni saqlash uchun rememberSaveable yoki ViewModel dan foydalaning.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "main"
) {
composable("main") { MainScreen(navController) }
composable("details") { DetailsScreen(navController) }
}
}
NavController konfiguratsiyasiga quyidagilar kiradi: NavHostController (asosiy), TestNavHostController (testlash) va ScopedNavController (ichki grafalar uchun bola). BottomNavigation uchun NavController butun ilova uchun yagona bo‘lishi kerak — har bir tabda yangi kontroller yaratish stekning yo‘qolishiga olib keladi. Kontrollerni ichki ekranlarga uzatish uchun o‘qilishni saqlash uchun CompositionLocalProvider emas, funksiya parametridan foydalaning.
Navigatsiyani testlash uchun compose-test-rule bilan TestNavHostController dan foydalaning. Kontroller boshlang‘ich marshrutni o‘rnatish va navigate() kutilgan o‘tishni chaqirganini tekshirish imkonini beradi. NavController testlash emulyatorni talab qilmaydi — Compose Test Semantics matcherlari bilan ishlaydi.
navigate(route: String) metodi — NavController-da navigatsiyaning asosiy usuli. Marshrut qatori, ixtiyoriy NavOptions va Navigator.Extras ni qabul qiladi. NavOptions o‘tish harakatini boshqaradi: launchSingleTop (marshrutni stekda takrorlamaslik), popUpTo (stekni marshrutgacha tozalash), restoreState (oldingi holatni tiklash).
NavOptions builder sintaksisi orqali o‘rnatiladi: NavOptionsBuilder. Asosiy parametrlar: popUpTo (route + inclusive/saveState), launchSingleTop (Boolean, true — dublikat yaratmaslik), restoreState (qaytishda holatni tiklash). popUpTo bo‘lmasa, har bir navigate() stekka yozuv qo‘shadi, bu back stack-ning to‘planishiga va Back tugmasining noto‘g‘ri ishlashiga olib keladi.
navController.navigate("profile/42") {
popUpTo("main") { saveState = true }
launchSingleTop = true
restoreState = true
}
Navigator.Extras marshrutga kirmaydigan qo‘shimcha ma’lumotlarni uzatish imkonini beradi: animatsiya uchun shared element, Intent bayroqlari, Pac-Man bundle. Extras kamdan-kam ishlatiladi — asosan Accompanist Animation yoki maxsus Navigator bilan integratsiya uchun. Aksariyat stsenariylar uchun marshrut qatori va NavOptions yetarli.
popBackStack() — oldingi ekranga qaytish metodi. Argumentlarsiz stekning yuqori yozuvini o‘chiradi va muvaffaqiyatli bo‘lsa true qaytaradi. Stek bo‘sh bo‘lsa — metod false qaytaradi va Activity yopiladi (super.onBackPressed() ga o‘xshash).
Yuklangan versiya popBackStack(route: String, inclusive: Boolean) belgilangan marshrutgacha barcha yozuvlarni o‘chiradi. inclusive = true bo‘lsa — belgilangan marshrut ham o‘chiriladi. Metod Boolean qaytaradi — yozuvlar topilgan va o‘chirilgan bo‘lsa true. Inclusive versiyasi avtorizatsiya yoki buyurtma berishdan keyin ‘‘ildiz ekranga chiqish’’ stsenariylari uchun foydali.
| Metod | Tavsif | Misol |
|---|---|---|
| popBackStack() | Bir ekran orqaga qaytish | navController.popBackStack() |
| popBackStack(route, false) | Marshrutgacha tozalash (marshrut qoladi) | popBackStack("home", false) |
| popBackStack(route, true) | Marshrutgacha va uni ham tozalash | popBackStack("home", true) |
| navigate(route) { popUpTo(route) { inclusive = true } } | To‘liq tozalash bilan o‘tish | navigate("login") { popUpTo(0) { inclusive = true } } |
Tizimning Back tugmasini (hardware back button) boshqarish uchun Compose-dan BackHandler dan foydalaning. BackHandler enabled va onBack — bosilganda chaqiriladigan callback ni qabul qiladi. Android 14+ uchun NavController 2.9.0 versiyasidan integratsiya qilingan PredictiveBackGesture ishlatiladi. Predictive back qaytishni oldindan ko‘rish animatsiyasini qo‘shadi.
SavedStateHandle — navigatsiya va rekonfiguratsiya vaqtida ViewModel holatini saqlash mexanizmi. NavController har bir NavBackStackEntry uchun avtomatik SavedStateHandle taqdim etadi. SavedStateHandle orqali ViewModel ekran holatini saqlaydi va qaytishda tiklaydi (restoreState = true).
Navigation Compose-da SavedStateHandle ViewModel bilan birgalikda ishlatiladi: ViewModel backStackEntry dan uzatiladigan SavedStateHandle orqali ishga tushiriladi. Boshqa ekranga o‘tish va qaytishda (restoreState bilan) ViewModel saqlangan holatni oladi, qayta yaratilmaydi. Bu ma’lumot kiritish, filtrlar yoki aylantirish bilan ekranlar uchun juda muhim.
class ProfileViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val userId: String = savedStateHandle.get<String>("userId") ?: ""
var searchQuery by savedStateHandle.getStateFlow("search", "")
.collectAsState()
}
SavedStateHandle primitiv turlarni, String, Bundle va Parcelable-ni qo‘llab-quvvatlaydi. Murakkab ob'ektlar uchun faqat ID ni saqlang, to‘liq ma’lumotlarni repozitariydan yuklang. SavedStateHandle chegarasi taxminan 1 MB, oshirish TransactionTooLargeException-ga sabab bo‘ladi. Katta hajmlar uchun handle-da saqlash o‘rniga Room yoki DataStore dan foydalaning.
Muhim: SavedStateHandle faqat NavOptions da restoreState = true ishlatilganda holatni saqlaydi. restoreState ko‘rsatilmagan bo‘lsa, qaytishda ViewModel standart qiymatlar bilan qayta yaratiladi. restoreState bilan BottomNavigation-ni almashtirish uchun NavController har bir tabning holatini saqlaydi va qayta tanlashda tiklaydi.
currentBackStackEntryAsState() — joriy marshrutning har bir o‘zgarishida yangilanadigan State<NavBackStackEntry?> qaytaruvchi funksiya. Bu UI-ni navigatsiya bilan sinxronizatsiya qilishning asosiy mexanizmi: BottomNavigation faol elementni ajratib ko‘rsatadi, Toolbar sarlavhani yangilaydi, Drawer o‘tish vaqtida yopiladi.
Funksiya snapshotFlow va collectAsState orqali ishlaydi: back stack o‘zgarganda, Compose obuna bo‘lgan elementlarni qayta kompozitsiya qiladi. Muhim: currentBackStackEntryAsState() faqat o‘tish animatsiyasi tugaganidan keyin yangilanadi. Darhol yangilash uchun navigate() bilan sinxron o‘zgaradigan, lekin holatni qo‘llab-quvvatlamaydigan currentDestination dan foydalaning.
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
Text(
text = when (currentRoute) {
"home" -> "Home"
"profile" -> "Profile"
else -> ""
}
)
Joriy marshrut argumentlariga kirish uchun navBackStackEntry?.arguments dan foydalaning. Bu BottomNavigation da qulay: selectedItem currentRoute asosida hisoblanadi. Navigatsiyani tuzatish uchun har bir o‘tishni qayd qiluvchi NavController.addOnDestinationChangedListener() dan foydalaning. Production-da ko‘p sonli composable ichida obunalardan saqlaning — ViewModel da yagona manba yarating va State-ni UI-ga uzating.
Tez-tez beriladigan savollar
Texnik jihatdan ha, lekin tavsiya etilmaydi. Yagona NavController izchil back stack ni ta’minlaydi va tuzatishni soddalashtiradi. Bir nechta kontrollerlar faqat alohida navigatsiyaga ega ichki grafalar uchun oqlanadi (masalan, o‘z stekiga ega modal bottom sheet).
NavController-ni ViewModel-ga konstruktor yoki DI orqali uzating. Biroq, NavController-ning o‘zini emas, faqat callback funksiyalarini (onNavigate, onBack) uzatish yaxshiroq — bu testlashni soddalashtiradi. Voqealar uchun ViewModel da Channel<NavEvent> dan foydalaning va UI-da yig‘ing.
Muammo hayotiy siklida: agar NavController hali ishga tushirilmagan bo‘lsa (NavHost qurilmagan), navigate() e’tiborga olinmaydi. Ma’lumotlar yuklangandan keyin navigatsiyani chaqirish uchun ixtiyoriy lifecycle bilan coroutine ichida emas, LaunchedEffect dan foydalaning.
navController.navigate("target") { popUpTo(0) { inclusive = true } } ni chaqiring. popUpTo(0) parametri stekni butunlay tozalaydi, inclusive = true boshlang‘ich yozuvni ham o‘chiradi. launchSingleTop = true bayrog‘i yangi marshrutning takrorlanishini oldini oladi.
NavHostController — NavHost uchun qo‘shimcha metodlarga ega NavController vorisi (masalan, setOnBackStackChangedListener). NavController — NavHost dan tashqarida stekni dasturiy boshqarish uchun ishlatilishi mumkin bo‘lgan asosiy sinf. Aksariyat hollarda NavHostController ishlatiladi.
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.