NavController Navigation Compose kitabxanasının mərkəzi komponentidir, Android tətbiqlərində naviqasiya yığınını və back stack vəziyyətini idarə edir. NavController vasitəsilə ekranlar arasında keçidlər, əvvəlki səhifələrə qayıdış və marşrutlar arasında məlumat ötürülməsi həyata keçirilir. Android Developers (2025) məlumatlarına görə, NavController birdən çox ekranı olan istənilən Compose tətbiqinin məcburi elementidir. Kontroller rememberNavController() vasitəsilə yaradılır, NavHost-a ötürülür və kompozisiyanın istənilən nöqtəsindən navigate() çağırışı üçün əlçatandır. Daxili SavedStateHandle dəstəyi rekonfiqurasiya zamanı ViewModel vəziyyətini avtomatik saxlayır.
Əsas məqamlar
NavController — Navigation Compose kitabxanasından olan sinifdir, Compose tətbiqləri üçün naviqasiya kontrollerini tətbiq edir. NavController NavBackStackEntry yığınını idarə edir, burada hər bir qeyd marşrut, arqumentlər və ekran vəziyyətini ehtiva edir. Kontroller əsas naviqasiya əməliyyatlarını dəstəkləyir: keçid, qayıdış, əvəzetmə və təmizləmə.
Naviqasiyanın FragmentManager və ya Intent vasitəsilə getdiyi View sistemindən fərqli olaraq, NavController yalnız Compose kontekstində işləyir. Back stack Fragment yığını deyil, NavDestination qrafı şəklində saxlanılır. Bu, Fragment yaradılması və məhv edilməsi üzərində overhead-i aradan qaldırır, həmçinin testləri sadələşdirir — NavController TestNavHostController vasitəsilə mock edilə bilər.
NavController NavHost ilə sıx bağlıdır — qrafdan cari ekranı render edən konteyner. NavHost olmadan NavController composable funksiyalarını göstərə bilməz, lakin yığını idarə etmək qabiliyyətini saxlayır. Tipik arxitekturada NavController Activity və ya əsas composable səviyyəsində yaradılır və parametrlər vasitəsilə kompozisiya ağacı boyunca aşağı ötürülür.
Google məlumatlarına görə, NavController bir neçə major buraxılış keçmişdir. Versiya 2.8.0 Type-Safe Navigation əlavə etdi, versiya 2.9.0 — predictive back gesture (Android 14+) dəstəyini. Kontroller Material3 Scaffold və BottomNavigation ilə uyğundur. Multimodul layihələr üçün NavController DI (Hilt/Koin) və ya konstruktor parametrləri vasitəsilə ötürülür.
NavController rememberNavController() composable funksiyası vasitəsilə yaradılır. Funksiya cari composable-ın həyat dövrünə bağlı NavHostController (NavController-ün varisi) nümunəsini qaytarır. Kompozisiyadan çıxdıqda kontroller təmizlənir. Rekonfiqurasiya zamanı kontrolleri saxlamaq üçün rememberSaveable və ya ViewModel istifadə edin.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "main"
) {
composable("main") { MainScreen(navController) }
composable("details") { DetailsScreen(navController) }
}
}
NavController konfiqurasiyasına daxildir: NavHostController (əsas), TestNavHostController (test) və ScopedNavController (iç-içə qraflar üçün uşaq). BottomNavigation üçün NavController bütün tətbiq üçün vahid olmalıdır — hər bir tabda yeni kontroller yaratmaq yığının itirilməsinə səbəb olacaq. Kontrolleri iç-içə ekranlara ötürmək üçün oxunaqlılığı qorumaq üçün CompositionLocalProvider deyil, funksiya parametrindən istifadə edin.
Naviqasiya testi üçün compose-test-rule ilə TestNavHostController istifadə edin. Kontroller ilkin marşrutu təyin etməyə və navigate() gözlənilən keçidi çağırdığını yoxlamağa imkan verir. NavController testi emulyator tələb etmir — Compose Test Semantics matçerləri ilə işləyir.
navigate(route: String) metodu — NavController-da naviqasiyanın əsas üsuludur. Marşrut sətri, opsional NavOptions və Navigator.Extras qəbul edir. NavOptions keçid davranışını idarə edir: launchSingleTop (yığında marşrutu dublikat etmə), popUpTo (yığını marşruta qədər təmizlə), restoreState (əvvəlki vəziyyəti bərpa et).
NavOptions builder sintaksisi ilə təyin edilir: NavOptionsBuilder. Əsas parametrlər: popUpTo (route + inclusive/saveState), launchSingleTop (Boolean, true — dublikat yaratma), restoreState (qayıdışda vəziyyəti bərpa et). popUpTo olmadan hər navigate() yığına giriş əlavə edir, bu da back stack-in yığılmasına və Back düyməsinin düzgün işləməməsinə səbəb olur.
navController.navigate("profile/42") {
popUpTo("main") { saveState = true }
launchSingleTop = true
restoreState = true
}
Navigator.Extras marşruta daxil olmayan əlavə məlumatları ötürməyə imkan verir: animasiya üçün shared element, Intent bayraqları, Pac-Man bundle. Extras nadir hallarda istifadə olunur — əsasən Accompanist Animation və ya fərdi Navigator ilə inteqrasiya üçün. Əksər ssenarilər üçün marşrut sətri və NavOptions kifayətdir.
popBackStack() — əvvəlki ekrana qayıtmaq üçün metod. Arqumentsiz yığının yuxarı girişini silir və uğurlu olarsa true qaytarır. Yığın boşdursa — metod false qaytarır və Activity bağlanır (super.onBackPressed() analoqu).
Yüklənmiş versiya popBackStack(route: String, inclusive: Boolean) göstərilən marşruta qədər bütün girişləri silir. inclusive = true olarsa — göstərilən marşrut da silinir. Metod Boolean qaytarır — girişləri tapmaq və silmək mümkün olduqda true. Inclusive versiyası avtorizasiya və ya sifariş vermədən sonra "kök ekrana çıxış" ssenariləri üçün faydalıdır.
| Metod | Təsvir | Nümunə |
|---|---|---|
| popBackStack() | Bir ekran geri qayıt | navController.popBackStack() |
| popBackStack(route, false) | Marşruta qədər təmizlə (route qalır) | popBackStack("home", false) |
| popBackStack(route, true) | Marşruta qədər və onunla birlikdə təmizlə | popBackStack("home", true) |
| navigate(route) { popUpTo(route) { inclusive = true } } | Tam təmizləmə ilə keçid | navigate("login") { popUpTo(0) { inclusive = true } } |
Sistem Back düyməsini (hardware back button) idarə etmək üçün Compose-dan BackHandler istifadə edin. BackHandler enabled və onBack — basıldıqda çağırılan callback qəbul edir. Android 14+ üçün NavController 2.9.0 versiyasından inteqrasiya edilən PredictiveBackGesture istifadə olunur. Predictive back qayıdışın önizləmə animasiyasını əlavə edir.
SavedStateHandle — naviqasiya və rekonfiqurasiya zamanı ViewModel vəziyyətini saxlamaq mexanizmidir. NavController hər NavBackStackEntry üçün avtomatik SavedStateHandle təqdim edir. SavedStateHandle vasitəsilə ViewModel ekran vəziyyətini saxlayır və qayıdışda bərpa edir (restoreState = true).
Navigation Compose-da SavedStateHandle ViewModel ilə birlikdə istifadə olunur: ViewModel backStackEntry-dən ötürülən SavedStateHandle vasitəsilə başladılır. Başqa ekrana keçid və qayıdışda (restoreState ilə) ViewModel saxlanmış vəziyyəti alır, yenidən yaradılmır. Bu, məlumat daxil etmə, filtr və ya sürüşdürmə ilə ekranlar üçün kritikdir.
class ProfileViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val userId: String = savedStateHandle.get<String>("userId") ?: ""
var searchQuery by savedStateHandle.getStateFlow("search", "")
.collectAsState()
}
SavedStateHandle primitiv tipləri, String, Bundle və Parcelable dəstəkləyir. Mürəkkəb obyektlər üçün yalnız ID saxlayın, tam məlumatları depodan yükləyin. SavedStateHandle limiti təxminən 1 MB-dır, aşılması TransactionTooLargeException-a səbəb olur. Böyük həcmlər üçün handle-də saxlamaq əvəzinə Room və ya DataStore istifadə edin.
Vacib: SavedStateHandle yalnız NavOptions-da restoreState = true istifadə edildikdə vəziyyəti saxlayır. restoreState göstərilməyibsə, qayıdışda ViewModel standart dəyərlərlə yenidən yaradılır. restoreState ilə BottomNavigation dəyişdirilməsi üçün NavController hər tabın vəziyyətini saxlayır və təkrar seçimdə bərpa edir.
currentBackStackEntryAsState() — cari marşrutun hər dəyişməsində yenilənən State<NavBackStackEntry?> qaytaran funksiyadır. Bu, UI-ni naviqasiya ilə sinxronizasiya etmək üçün əsas mexanizmdir: BottomNavigation aktiv elementi vurğulayır, Toolbar başlığı yeniləyir, Drawer keçid zamanı bağlanır.
Funksiya snapshotFlow və collectAsState vasitəsilə işləyir: back stack dəyişdikdə Compose abunə olunmuş elementləri yenidən kompozisiya edir. Vacib: currentBackStackEntryAsState() yalnız keçid animasiyası bitdikdən sonra yenilənir. Dərhal yeniləmə üçün navigate() ilə sinxron dəyişən, lakin vəziyyəti dəstəkləməyən currentDestination istifadə edin.
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
Text(
text = when (currentRoute) {
"home" -> "Home"
"profile" -> "Profile"
else -> ""
}
)
Cari marşrutun arqumentlərinə giriş üçün navBackStackEntry?.arguments istifadə edin. Bu, BottomNavigation-da rahatdır: selectedItem currentRoute əsasında hesablanır. Naviqasiya debug üçün hər keçidi qeyd edən NavController.addOnDestinationChangedListener() istifadə edin. Production-da çox sayda composable daxilində abunələrdən qaçın — ViewModel-də vahid mənbə yaradın və UI-ə State ötürün.
Tez-tez verilən suallar
Texniki olaraq bəli, lakin tövsiyə edilmir. Vahid NavController ardıcıl back stack təmin edir və debug-u sadələşdirir. Çoxsaylı kontrollerlər yalnız ayrı naviqasiyası olan iç-içə qraflar üçün əsaslandırılır (məsələn, öz yığını olan modal bottom sheet).
NavController-ü ViewModel-ə konstruktor və ya DI vasitəsilə ötürün. Bununla belə, NavController-in özünü deyil, yalnız callback funksiyalarını (onNavigate, onBack) ötürmək daha yaxşıdır — bu, testləri sadələşdirir. Hadisələr üçün ViewModel-də Channel<NavEvent> istifadə edin və UI-də toplayın.
Problem həyat dövründədir: NavController hələ başladılmamışdırsa (NavHost qurulmayıb), navigate() nəzərə alınmır. Məlumat yükləndikdən sonra naviqasiyanı çağırmaq üçün ixtiyari lifecycle ilə coroutine daxilində deyil, LaunchedEffect istifadə edin.
navController.navigate("target") { popUpTo(0) { inclusive = true } } çağırın. popUpTo(0) parametri yığını tamamilə təmizləyir, inclusive = true başlanğıc girişi də silir. launchSingleTop = true bayrağı yeni marşrutun dublikat edilməsinin qarşısını alır.
NavHostController — NavHost üçün əlavə metodları olan NavController varisidir (məsələn, setOnBackStackChangedListener). NavController — NavHost xaricində yığını proqramlı idarə etmək üçün istifadə oluna bilən əsas sinifdir. Əksər hallarda NavHostController istifadə olunur.
Xülasə
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.
Həm də oxuyun