NavHost — Jetpack Compose-da naviqasiya qrafı üçün giriş nöqtəsi rolunu oynayan composable konteynerdir. O, NavController-u marşrutlar dəsti ilə əlaqələndirir və back stack vəziyyətindən asılı olaraq cari ekranı göstərir. Android Developers (2025) məlumatına görə, NavHost naviqasiyalı istənilən Compose tətbiqi üçün məcburi komponentdir. NavHost daxilində isteğe bağlı arqumentlər, deep links və animasiya ilə composable marşrutlar qeydiyyatdan keçirilir. Hər marşrut — NavBackStackEntry qəbul edən adi composable funksiyadır. NavHost back press, vəziyyətin saxlanması və rekonfiqurasiya zamanı bərpanı avtomatik idarə edir.
Əsas məqamlar
NavHost — cari naviqasiya ekranını göstərmək üçün konteyner təmin edən composable funksiyadır. NavHost NavController, startDestination və Kotlin DSL ilə qurulmuş marşrut qrafını qəbul edir. Cari marşrut dəyişdikdə NavHost göstərilən composable-ı müəyyən edilmiş animasiya ilə dəyişir.
NavHost ekran dəyişdirici kimi işləyir: NavController-dan cari NavBackStackEntry-i izləyir və müvafiq composable bloku göstərir. Hər ekran — NavBackStackEntry qəbul edən müstəqil composable funksiyadır. Bütün ekranlar vahid kompozisiya ağacında mövcuddur, lakin NavHost yalnız birini göstərir, qalanlarını animasiya ilə gizlədir.
FragmentManager-dən fərqli olaraq, NavHost hər ekran üçün Fragment yaratmır. Bütün lifecycle CompositionLifecycle vasitəsilə idarə olunur — composable funksiyalarının onStart/onResume-u yoxdur, buna görə də side-effektlər üçün LaunchedEffect və DisposableEffect istifadə olunur. NavHost avtomatik olaraq NavController-a abunə olur və marşrut dəyişdikdə UI-ni yenidən qurur.
Google məlumatına görə, NavHost Navigation 2.4.0 versiyasından etibarən stable API-dir. 2.8.0 versiyasından başlayaraq NavHost Kotlin Serialization vasitəsilə Type-Safe Navigation-ı dəstəkləyir ki, bu da string route-ları data-klaslarla əvəz edir. NavHost həmçinin iç-içə qrafları dəstəkləyir ki, bu da modullar üzrə naviqasiyanı təşkil etməyə imkan verir.
NavHost iki məcburi parametrlə yaradılır: navController (NavHostController nümunəsi) və startDestination (ilk ekranın marşrut string-i). Üçüncü parametr — builder blokudur ki, orada bütün marşrutlar composable(), navigation() və dialog() vasitəsilə qeydiyyatdan keçirilir.
@Composable
fun AppNavHost(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(navController) }
composable("settings") { SettingsScreen(navController) }
}
}
startDestination — NavHost ilk dəfə işə salındıqda açılan marşrutdur. Back stack boşdursa, NavHost avtomatik olaraq startDestination-ı steka əlavə edir. Rekonfiqurasiya zamanı (ekranın döndərilməsi) NavHost savedState-dən son marşrutu bərpa edir, startDestination-ı yox.
BottomNavigation üçün startDestination aşağı panelin marşrutlarından biridir. Panelin qalan marşrutları ayrı composable qeydləri kimi əlavə edilir. NavHost Scaffold.content daxilində — tətbiqin əsas məzmununun göstərildiyi yerdə yerləşdirilməlidir. NavHost TopAppBar və BottomNavigation çıxıldıqdan sonra qalan bütün hündürlüyü tutur.
composable(route, arguments, deepLinks, enterTransition, exitTransition, content) funksiyası NavHost qrafında marşrutu qeydiyyatdan keçirir. route parametri — {paramName} formatında isteğe bağlı placeholderları olan yolu təsvir edən stringdir. Placeholder naviqasiya zamanı konkret dəyərlə əvəz olunur.
Content bloku NavBackStackEntry qəbul edir ki, ondan arqumentlər çıxarılır. Ekranın composable funksiyası yalnız NavController-un cari marşrutu route ilə uyğun gəldikdə göstərilir. Uyğunsuzluq halında composable kompozisiyadan silinir, lakin onun vəziyyəti rememberSaveable və ya SavedStateHandle ilə ViewModel vasitəsilə saxlanıla bilər.
composable(
route = "article/{articleId}",
arguments = listOf(navArgument("articleId") {
type = NavType.IntType
defaultValue = 0
}),
deepLinks = listOf(navDeepLink { uriPattern = "https://app.example/article/{articleId}" })
) { backStackEntry ->
val articleId = backStackEntry.arguments?.getInt("articleId") ?: 0
ArticleScreen(articleId = articleId)
}
NavHost daxilində composable qeydlərinin sayı istənilən ola bilər — bir neçədən yüzlərlə qədər. Böyük tətbiqlər üçün marşrutlar modullara bölünür və iç-içə qraflar vasitəsilə qoşulur. Hər composable-ın öz animasiya, deep links və arqument parametrləri ola bilər.
Marşrut arqumentləri composable()-da arguments: List<NamedNavArgument> parametri ilə təyin edilir. Hər arqument navArgument(name) { type; defaultValue } vasitəsilə müəyyən edilir. NavType arqumentin tipini təyin edir: StringType, IntType, LongType, FloatType, BoolType, ParcelableType və ReferenceType.
| Marşrut parametri | Route nümunəsi | NavType |
|---|---|---|
| Yol (path) | "user/{id}" | NavType.IntType |
| Sorğu (query) | "search?q={query}" | NavType.StringType |
| İsteğe bağlı | "details/{id}?tab={tab}" | StringType + defaultValue="" |
| Parcelable | "checkout/{order}" | NavType.ParcelableType |
Arqumentlər NavBackStackEntry-dən arguments?.getInt("id") vasitəsilə çıxarılır. Məcburi arqumentlər üçün defaultValue buraxıla bilər — NavType null istifadə edəcək. İsteğe bağlı arqumentlər üçün defaultValue məcburidir, əks halda parametr olmadıqda naviqasiya istisna atacaq.
Navigation 2.8.0 versiyasından Type-Safe Navigation tövsiyə olunur: Kotlin Serialization ilə marşrutlar üçün sealed class və ya data class təyin edin. String route əvəzinə composable<RouteType> { backStackEntry -> } istifadə edin. Bu, route-da səhvləri aradan qaldırır və arqumentlər üçün NavType-ı avtomatik yaradır. Miqrasiya üçün navigation-compose-typesafe asılılığını və Kotlin Serialization plaginini əlavə edin.
nested graphs — navigation(route, startDestination) funksiyası vasitəsilə NavHost daxilində marşrutların qruplaşdırılması mexanizmidir. İç-içə qrafın öz route prefiksi və startDestination-ı var, bütün marşrutları prefiks vasitəsilə əlçatandır. nested graphs modul arxitekturası üçün istifadə olunur, burada hər feature modul öz altqrafını qeydiyyatdan keçirir.
İç-içə qrafların üstünlükləri: marşrutların modul daxilində izolyasiyası, ekranlar qrupu üçün vahid back stack, daxili strukturu açıqlamadan prefiks üzrə naviqasiya imkanı. Məsələn, "auth" qrafı "auth/login" və "auth/register" marşrutlarını ehtiva edir. Naviqasiya həm tam marşrut üzrə, həm də startDestination-a yönləndirmə ilə prefiks üzrə mümkündür.
NavHost(navController = navController, startDestination = "main") {
composable("main") { MainScreen(navController) }
navigation(
route = "auth",
startDestination = "auth/login"
) {
composable("auth/login") { LoginScreen(navController) }
composable("auth/register") { RegisterScreen(navController) }
}
}
nested graphs arqumentlərin qraf səviyyəsində ötürülməsini dəstəkləyir: qrafın route-da elan edilmiş parametrlər bütün daxili marşrutlara ötürülür. İç-içə qrafı təmizləmək üçün popBackStack(route) istifadə edin — bütün daxili qeydləri siləcək. İç-içə qrafların dərinlik məhdudiyyəti yoxdur, lakin oxunaqlılıq üçün 3 səviyyədən çox olmaması tövsiyə olunur.
NavHost composable marşrutlar arasında keçid animasiyasını enterTransition, exitTransition, popEnterTransition və popExitTransition parametrləri vasitəsilə dəstəkləyir. Animasiyalar bir dəfə NavHost üçün təyin edilir və bütün marşrutlara tətbiq olunur, ya da hər composable üçün fərdi şəkildə. Standart olaraq animasiya söndürülüb.
Tipik konfiqurasiya: enterTransition = slideInHorizontally(initialOffsetX = { it }) — ekran sağdan daxil olur; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — ekran sola çıxır. Pop-animasiya üçün istiqamətlər güzgülənir: ekran soldan daxil olur və sağa çıxır. BottomNavigation üçün slidesız fadeIn/fadeOut istifadə olunur.
NavHost(
navController = navController,
startDestination = "home",
enterTransition = { slideInHorizontally(initialOffsetX = { it }) + fadeIn() },
exitTransition = { slideOutHorizontally(targetOffsetX = { -it }) + fadeOut() },
popEnterTransition = { slideInHorizontally(initialOffsetX = { -it }) + fadeIn() },
popExitTransition = { slideOutHorizontally(targetOffsetX = { it }) + fadeOut() }
) { /* composable routes */ }
Xüsusi animasiyalar Compose Animation API vasitəsilə yaradılır: AnimatedContentTransitionScope konteyner ölçülərinə, animasiya gedişatına və direction-a giriş təmin edir. Shared element transition üçün (bir elementin digər ekrana rəvan keçidi) Accompanist Navigation Animation kitabxanası və ya sharedElement Modifier vasitəsilə xüsusi tətbiq tələb olunur. Android Developers (2025) məlumatına görə, standart slide animasiyası (sağdan daxil, sola çıxış) naviqasiyalı Android tətbiqlərinin 80%-də istifadə olunur.
Tez-tez verilən suallar
Texniki olaraq bəli, lakin tövsiyə edilmir. Hər NavHost müstəqil back stack yaradır ki, bu da vahid naviqasiyanı pozur. İstisna — ayrı sahələrdir, məsələn, əsas məzmun üçün NavHost və öz naviqasiyası olan BottomSheet üçün NavHost.
NavHost — ekranları dəyişdirən naviqasiya konteyneri. Scaffold — bütün səhifənin layout-u (TopAppBar, BottomNavigation, FloatingActionButton). Adətən NavHost Scaffold.content daxilində yerləşdirilir. Scaffold naviqasiyanı idarə etmir, yalnız UI komponentləri üçün slotlar təmin edir.
ViewModel NavBackStackEntry çərçivəsində viewModel() vasitəsilə yaradılır. ViewModel-i ekranlar arasında paylaşmaq üçün parentNavController-dan istifadə edin: paylaşılan ViewModel-i valideyn entry-yə bağlayın. Alternativ — NavGraph scope-u ilə DI (Hilt/Koin).
Bu normal davranışdır — NavHost marşrutdan çıxdıqda composable-ı kompozisiyadan silir. Vəziyyəti saxlamaq üçün UI vəziyyəti üçün rememberSaveable və biznes məntiqi üçün SavedStateHandle ilə ViewModel istifadə edin.
Son marşrutu composable("404") əlavə edin və naməlum deep link zamanı ona naviqasiya edin. NavHost-da catch-all marşrut yoxdur — navigate() etməzdən əvvəl Deep Link intent handler-də marşrutu yoxlayın. Route tapılmadıqda — 404-ə navigate edin.
Nəticə
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