NavController — lényege, módszerei és navigációkezelés Jetpack Compose-ban

Szerző: IT Sectr Megjelenés: 2026-06-29 Olvasási idő: 7 perc

A NavController a Navigation Compose könyvtár központi komponense, amely a navigációs vermet és a back stack állapotát kezeli Android alkalmazásokban. A NavController segítségével történnek a képernyők közötti átmenetek, a visszatérés az előző oldalakra és az adatok továbbítása az útvonalak között. Az Android Developers (2025) szerint a NavController kötelező eleme minden több képernyős Compose alkalmazásnak. A vezérlő a rememberNavController() függvénnyel jön létre, átadódik a NavHost-nak és elérhető a navigate() meghívásához a kompozíció bármely pontjáról. A beépített SavedStateHandle támogatás automatikusan elmenti a ViewModel állapotát átkonfiguráláskor.

Főbb pontok

  • NavController — a Compose navigáció központi vezérlője, kezeli a back stack-et és a képernyők közötti átmeneteket
  • navigate() — az útvonalra való átmenet elsődleges metódusa NavOptions támogatással a verem kezeléséhez
  • popBackStack() — visszatérés az előző képernyőre opcionális törléssel a megadott útvonalig
  • SavedStateHandle — integráció a ViewModel-lel a képernyő állapotának mentéséhez navigáció során
  • currentBackStackEntryAsState() — az aktuális útvonal megfigyelése az UI szinkronizálásához

Mi az a NavController Jetpack Compose-ban?

NavController — egy osztály a Navigation Compose könyvtárból, amely megvalósítja a navigációs vezérlőt Compose alkalmazások számára. A NavController kezeli a NavBackStackEntry vermet, ahol minden bejegyzés tartalmazza az útvonalat, argumentumokat és képernyő állapotot. A vezérlő támogatja az alapvető navigációs műveleteket: átmenet, visszatérés, csere és törlés.

Ellentétben a View rendszerrel, ahol a navigáció FragmentManager-en vagy Intent-en keresztül történt, a NavController kizárólag a Compose kontextusban működik. A back stack NavDestination gráfként van tárolva, nem Fragment veremként. Ez kiküszöböli a Fragment létrehozásának és megsemmisítésének többletterhelését, és egyszerűsíti a tesztelést — a NavController a TestNavHostController segítségével mockolható.

A NavController szorosan kapcsolódik a NavHost-hoz — a tartályhoz, amely a gráfból rendereli az aktuális képernyőt. NavHost nélkül a NavController nem tud composable függvényeket megjeleníteni, de megtartja a verem kezelésének képességét. Tipikus architektúrában a NavController az Activity vagy a fő composable szintjén jön létre, és paramétereken keresztül adódik le a kompozíciós fa mentén.

Google szerint a NavController több nagy kiadáson esett át. A 2.8.0 verzió hozzáadta a Type-Safe Navigation-t, a 2.9.0 verzió — a predictive back gesture (Android 14+) támogatást. A vezérlő kompatibilis a Material3 Scaffold és BottomNavigation komponensekkel. Többmodulos projektekhez a NavController DI-n (Hilt/Koin) vagy konstruktor paramétereken keresztül adódik át.

A NavController a rememberNavController() composable függvénnyel jön létre. A függvény egy NavHostController példányt (NavController leszármazott) ad vissza, amely az aktuális composable életciklusához van kötve. A kompozíció elhagyásakor a vezérlő törlődik. A vezérlő átkonfiguráláskor történő mentéséhez használja a rememberSaveable vagy ViewModel elemet.

kotlin
@Composable
fun MyApp() {
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = "main"
    ) {
        composable("main") { MainScreen(navController) }
        composable("details") { DetailsScreen(navController) }
    }
}

A NavController konfigurációja tartalmazza: NavHostController (fő), TestNavHostController (tesztelés) és ScopedNavController (gyermek beágyazott gráfokhoz). BottomNavigation esetén a NavController-nak egyedinek kell lennie a teljes alkalmazásban — új vezérlő létrehozása minden lapon a verem elvesztéséhez vezet. A vezérlő beágyazott képernyőkre történő átadásához használja a függvény paraméterét, ne a CompositionLocalProvider-t, az olvashatóság megőrzése érdekében.

A navigáció teszteléséhez használja a TestNavHostController-t compose-test-rule-lal. A vezérlő lehetővé teszi a kezdeti útvonal beállítását és annak ellenőrzését, hogy a navigate() a várt átmenetet hívta-e. A NavController tesztelése nem igényel emulátort — a Compose Test Semantics matchereivel működik.

A navigate(route: String) metódus — a navigáció elsődleges módja a NavController-ben. Egy útvonal stringet, opcionális NavOptions-t és Navigator.Extras-t fogad. A NavOptions kezeli az átmenet viselkedését: launchSingleTop (ne duplikálja az útvonalat a veremben), popUpTo (törölje a vermet az útvonalig), restoreState (állítsa vissza az előző állapotot).

A NavOptions builder szintaxissal állítható be: NavOptionsBuilder. Fő paraméterek: popUpTo (route + inclusive/saveState), launchSingleTop (Boolean, true — ne hozzon létre duplikátumot), restoreState (állítsa vissza az állapotot visszatéréskor). popUpTo nélkül minden navigate() bejegyzést ad a veremhez, ami a back stack felhalmozódásához és a Back gomb helytelen működéséhez vezet.

kotlin
navController.navigate("profile/42") {
    popUpTo("main") { saveState = true }
    launchSingleTop = true
    restoreState = true
}

A Navigator.Extras lehetővé teszi további adatok átadását, amelyek nem részei az útvonalnak: shared element animációhoz, Intent zászlók, Pac-Man bundle. Az Extras ritkán használatos — főleg Accompanist Animation vagy egyéni Navigator integrációjához. A legtöbb forgatókönyv esetén elegendő az útvonal string és a NavOptions.

popBackStack: visszatérés és veremtörlés kezelése

popBackStack() — metódus az előző képernyőre való visszatéréshez. Argumentumok nélkül eltávolítja a verem tetején lévő bejegyzést és true értéket ad vissza, ha a törlés sikeres. Ha a verem üres — a metódus false értéket ad vissza, és az Activity bezáródik (hasonlóan a super.onBackPressed()-hez).

A túlterhelt változat popBackStack(route: String, inclusive: Boolean) eltávolítja az összes bejegyzést a megadott útvonalig. Ha inclusive = true — a megadott útvonal is törlődik. A metódus Boolean értéket ad vissza — true, ha a bejegyzések megtalálhatók és eltávolíthatók. Az inclusive verzió hasznos a „kilépés a főképernyőre” forgatókönyvekhez autorizáció vagy rendelés leadása után.

MetódusLeírásPélda
popBackStack()Egy képernyővel visszalépésnavController.popBackStack()
popBackStack(route, false)Törlés az útvonalig (az útvonal marad)popBackStack("home", false)
popBackStack(route, true)Törlés az útvonalig és beleértvepopBackStack("home", true)
navigate(route) { popUpTo(route) { inclusive = true } }Átmenet teljes törlésselnavigate("login") { popUpTo(0) { inclusive = true } }

A rendszer Back gombjának (hardware back button) kezeléséhez használja a BackHandler-t a Compose-ból. A BackHandler elfogadja az enabled és onBack — a megnyomáskor meghívott callback-et. Android 14+ esetén a PredictiveBackGesture használatos, amely a NavController 2.9.0 verziótól integrálható. A Predictive back hozzáad egy előnézeti animációt a visszatéréshez.

SavedStateHandle: képernyő állapotának mentése

SavedStateHandle — a ViewModel állapotának mentési mechanizmusa navigáció és átkonfigurálás során. A NavController automatikusan biztosítja a SavedStateHandle-t minden NavBackStackEntry számára. A SavedStateHandle-en keresztül a ViewModel tárolja a képernyő állapotát és visszaállítja azt visszatéréskor (restoreState = true).

A Navigation Compose-ban a SavedStateHandle a ViewModel-lel együtt használatos: a ViewModel a backStackEntry-ből átadott SavedStateHandle-en keresztül inicializálódik. Másik képernyőre váltáskor és visszatéréskor (restoreState-val) a ViewModel a mentett állapotot kapja, nem jön lére újra. Ez kritikus az adatbevitelt, szűrőket vagy görgetést tartalmazó képernyők esetén.

kotlin
class ProfileViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    val userId: String = savedStateHandle.get<String>("userId") ?: ""
    var searchQuery by savedStateHandle.getStateFlow("search", "")
        .collectAsState()
}

A SavedStateHandle támogatja a primitív típusokat, String-et, Bundle-t és Parcelable-t. Összetett objektumok esetén csak az ID-t mentse, a teljes adatokat a tárolóból töltse be. A SavedStateHandle korlátja kb. 1 MB, túllépés esetén TransactionTooLargeException keletkezik. Nagy mennyiségekhez használja a Room vagy DataStore megoldást a handle-ben való mentés helyett.

Fontos: A SavedStateHandle csak akkor menti az állapotot, ha restoreState = true van használva a NavOptions-ban. Ha a restoreState nincs megadva, visszatéréskor a ViewModel alapértelmezett értékekkel jön létre újra. A BottomNavigation restoreState-val történő váltásakor a NavController minden lap állapotát elmenti és visszaállítja újraválasztáskor.

Aktuális útvonal megfigyelése a currentBackStackEntryAsState segítségével

currentBackStackEntryAsState() — függvény, amely State<NavBackStackEntry?> értéket ad vissza, amely minden aktuális útvonalváltozáskor frissül. Ez az UI navigációval való szinkronizálásának fő mechanizmusa: a BottomNavigation kiemeli az aktív elemet, a Toolbar frissíti a címet, a Drawer bezáródik átmenetkor.

A függvény a snapshotFlow és collectAsState segítségével működik: a back stack változásakor a Compose újrakomponálja a feliratkozott elemeket. Fontos: a currentBackStackEntryAsState() csak az átmeneti animáció befejeződése után frissül. Azonnali frissítéshez használja a currentDestination-t, amely szinkron változik a navigate()-val, de nem támogatja az állapotot.

kotlin
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route

Text(
    text = when (currentRoute) {
        "home" -> "Home"
        "profile" -> "Profile"
        else -> ""
    }
)

Az aktuális útvonal argumentumainak eléréséhez használja a navBackStackEntry?.arguments-t. Ez kényelmes BottomNavigation esetén: a selectedItem a currentRoute alapján számítódik ki. A navigáció hibakereséséhez használja a NavController.addOnDestinationChangedListener()-t, amely naplózza az egyes átmeneteket. Production-ben kerülje a feliratkozásokat nagyszámú composable-ben — hozzon létre egy forrást a ViewModel-ben és adja át a State-t az UI-nak.

Gyakran Ismételt Kérdések

Létrehozható több NavController egy Activity-ben?

Technikailag igen, de nem ajánlott. Egyetlen NavController konzisztens back stack-et biztosít és egyszerűsíti a hibakeresést. Több vezérlő csak beágyazott gráfokhoz indokolt külön navigációval (pl. modal bottom sheet saját veremmel).

Hogyan adjam át a NavController-t ViewModel-en keresztül?

Adja át a NavController-t a ViewModel-nek konstruktoron vagy DI-n keresztül. Azonban jobb csak callback függvényeket (onNavigate, onBack) átadni, nem magát a NavController-t — ez egyszerűsíti a tesztelést. Eseményekhez használja a Channel<NavEvent>-et a ViewModel-ben és gyűjtse össze az UI-ban.

Miért nem működik a navigate aszinkron művelet után?

A probléma az életciklusban van: ha a NavController még nincs inicializálva (NavHost nincs felépítve), a navigate() figyelmen kívül marad. A navigáció meghívásához adatok betöltése után használja a LaunchedEffect-et, ne egy coroutine-ban tetszőleges lifecyle-lal.

Hogyan töröljem a teljes back stack-et és lépjek új képernyőre?

Hívja a navController.navigate("target") { popUpTo(0) { inclusive = true } } parancsot. A popUpTo(0) paraméter teljesen törli a vermet, az inclusive = true eltávolítja a kezdeti bejegyzést is. A launchSingleTop = true zászló megakadályozza az új útvonal duplikálódását.

Mi a különbség a NavHostController és NavController között?

NavHostController — a NavController leszármazottja további metódusokkal a NavHost számára (pl. setOnBackStackChangedListener). NavController — az alaposztály, amely a NavHost-on kívül is használható a verem programozott kezeléséhez. A legtöbb esetben NavHostController-t használnak.

Összefoglaló

  • NavController — a Navigation Compose központi komponense, kezeli az útvonalak vermét és a képernyők közötti átmeneteket
  • navigate() átmenetet végez a popUpTo, launchSingleTop és restoreState beállításokkal a NavOptions-on keresztül
  • popBackStack() kezeli a visszatérést: egyetlen lépés vagy tömeges törlés a megadott útvonalig inclusive paraméterrel
  • SavedStateHandle integrálódik a ViewModel-lel a képernyő állapotának automatikus mentéséhez navigáció során
  • currentBackStackEntryAsState() reaktív megfigyelést biztosít az aktuális útvonalról az UI szinkronizálásához
  • BackHandler kezeli a rendszer Back gombját, a PredictiveBackGesture a NavController 2.9.0-tól támogatott
  • Teszteléshez használja a TestNavHostController-t compose-test-rule-lal és Semantics matcherekkel

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is