NavController — mahiyyəti, metodları və Jetpack Compose-da naviqasiya idarəetməsi

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

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 — Compose naviqasiyasının mərkəzi kontrolleri, back stack və ekranlar arası keçidləri idarə edir
  • navigate() — yığını idarə etmək üçün NavOptions dəstəyi ilə marşruta keçid üçün əsas metod
  • popBackStack() — göstərilən marşruta qədər opsional təmizləmə ilə əvvəlki ekrana qayıdış
  • SavedStateHandle — naviqasiya zamanı ekran vəziyyətini saxlamaq üçün ViewModel ilə inteqrasiya
  • currentBackStackEntryAsState() — UI sinxronizasiyası üçün cari marşrutun müşahidəsi

Jetpack Compose-da NavController nədir?

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.

kotlin
@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.

kotlin
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: qayıdış və yığının təmizlənməsi idarəetməsi

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.

MetodTəsvirNümunə
popBackStack()Bir ekran geri qayıtnavController.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çidnavigate("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: ekran vəziyyətinin saxlanması

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.

kotlin
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 vasitəsilə cari marşrutun müşahidəsi

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.

kotlin
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

Bir Activity-də bir neçə NavController yaratmaq mümkündürmü?

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 vasitəsilə necə ötürmək olar?

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.

Niyə navigate asinxron əməliyyatdan sonra işləmir?

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.

Bütün back stack-i necə təmizləmək və yeni ekrana keçmək olar?

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 NavController-dən nə ilə fərqlənir?

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ə

  • NavController — Navigation Compose-un mərkəzi komponenti, marşrut yığınını və ekranlar arası keçidləri idarə edir
  • navigate() NavOptions vasitəsilə popUpTo, launchSingleTop və restoreState parametrləri ilə keçid həyata keçirir
  • popBackStack() qayıdışı idarə edir: tək addım və ya inclusive ilə göstərilən marşruta qədər kütləvi təmizləmə
  • SavedStateHandle naviqasiya zamanı ekran vəziyyətinin avtomatik saxlanması üçün ViewModel ilə inteqrasiya olunur
  • currentBackStackEntryAsState() UI sinxronizasiyası üçün cari marşrutun reaktiv müşahidəsini təmin edir
  • BackHandler sistem Back düyməsini idarə edir, PredictiveBackGesture NavController 2.9.0-dan dəstəklənir
  • Test üçün compose-test-rule və Semantics matçerləri ilə TestNavHostController 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