NavHost je composable kontejner, který slouží jako vstupní bod pro navigační graf v Jetpack Compose. Propojuje NavController se sadou tras a vykresluje aktuální obrazovku v závislosti na stavu back stack. Podle Android Developers (2025) je NavHost povinnou komponentou pro každou Compose aplikaci s navigací. Uvnitř NavHost se registrují composable trasy s volitelnými argumenty, deep links a animací. Každá trasa je běžná composable funkce, která přijímá NavBackStackEntry s daty přechodu. NavHost automaticky zpracovává back press, ukládání stavu a obnovu při rekonfiguraci.
Hlavní body
NavHost je composable funkce, která poskytuje kontejner pro zobrazení aktuální navigační obrazovky. NavHost přijímá NavController, startDestination a graf tras vytvořený pomocí Kotlin DSL. Při změně aktuální trasy NavHost přepíná zobrazený composable se zadanou animací.
NavHost funguje jako přepínač obrazovek: sleduje aktuální NavBackStackEntry z NavController a vykresluje odpovídající composable blok. Každá obrazovka je nezávislá composable funkce, která přijímá NavBackStackEntry s argumenty trasy. Všechny obrazovky existují v jediném stromu kompozice, ale NavHost zobrazuje vždy jen jednu, ostatní skrývá pomocí animace.
Na rozdíl od FragmentManager, NavHost nevytváří Fragment pro každou obrazovku. Celý životní cyklus je řízen pomocí CompositionLifecycle — composable funkce nemají onStart/onResume, proto se pro vedlejší efekty používají LaunchedEffect a DisposableEffect. NavHost se automaticky přihlašuje k odběru NavController a překresluje UI při změně trasy.
Podle Google je NavHost stabilní API od verze Navigation 2.4.0. Od verze 2.8.0 NavHost podporuje Type-Safe Navigation pomocí Kotlin Serialization, což nahrazuje stringové route datovými třídami. NavHost také podporuje vnořené grafy, což umožňuje organizovat navigaci podle modulů.
NavHost se vytváří se dvěma povinnými parametry: navController (instance NavHostController) a startDestination (řetězec trasy první obrazovky). Třetím parametrem je builder blok, ve kterém se registrují všechny trasy pomocí composable(), navigation() a dialog().
@Composable
fun AppNavHost(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(navController) }
composable("settings") { SettingsScreen(navController) }
}
}
startDestination je trasa, která se otevře při prvním spuštění NavHost. Pokud je back stack prázdný, NavHost automaticky přidá startDestination do zásobníku. Při rekonfiguraci (otočení obrazovky) NavHost obnoví poslední trasu z savedState, nikoli startDestination.
Pro BottomNavigation je startDestination jednou z tras dolního panelu. Ostatní trasy panelu se přidávají jako samostatné composable záznamy. NavHost by měl být umístěn uvnitř Scaffold.content — tam, kde se zobrazuje hlavní obsah aplikace. NavHost zabírá celou dostupnou výšku minus TopAppBar a BottomNavigation.
Funkce composable(route, arguments, deepLinks, enterTransition, exitTransition, content) registruje trasu v grafu NavHost. Parametr route je řetězec popisující cestu s volitelnými placeholders ve tvaru {paramName}. Placeholder je při navigaci nahrazen konkrétní hodnotou.
Content blok přijímá NavBackStackEntry, ze kterého se extrahují argumenty. Composable funkce obrazovky se vykresluje pouze tehdy, když aktuální trasa NavController odpovídá route. Při neshodě je composable odstraněn z kompozice, ale jeho stav může být uložen pomocí rememberSaveable nebo ViewModel se SavedStateHandle.
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)
}
Počet composable záznamů uvnitř NavHost může být libovolný — od několika po stovky. Pro velké aplikace jsou trasy rozděleny podle modulů a propojeny pomocí vnořených grafů. Každý composable může mít vlastní nastavení animace, deep links a argumentů.
Argumenty trasy se definují pomocí parametru arguments: List<NamedNavArgument> v composable(). Každý argument se zadává pomocí navArgument(name) { type; defaultValue }. NavType určuje typ argumentu: StringType, IntType, LongType, FloatType, BoolType, ParcelableType a ReferenceType.
| Parametr trasy | Příklad route | NavType |
|---|---|---|
| Cesta (path) | „user/{id}" | NavType.IntType |
| Dotaz (query) | „search?q={query}" | NavType.StringType |
| Volitelný | „details/{id}?tab={tab}" | StringType + defaultValue="" |
| Parcelable | „checkout/{order}" | NavType.ParcelableType |
Argumenty se extrahují z NavBackStackEntry pomocí arguments?.getInt("id"). U povinných argumentů může defaultValue chybět — NavType použije null. U volitelných argumentů je defaultValue povinná, jinak navigace vyvolá výjimku při chybějícím parametru.
Od verze Navigation 2.8.0 se doporučuje Type-Safe Navigation: definujte sealed class nebo data class pro trasy s Kotlin Serialization. Místo stringového route použijte composable<RouteType> { backStackEntry -> }. To eliminuje překlepy v route a automaticky generuje NavType pro argumenty. Pro migraci přidejte závislost navigation-compose-typesafe a plugin Kotlin Serialization.
nested graphs — mechanismus seskupování tras uvnitř NavHost pomocí funkce navigation(route, startDestination). Vnořený graf má vlastní prefix route a startDestination a všechny jeho trasy jsou dostupné přes prefix. nested graphs se používají pro modulární architekturu, kde každý feature modul registruje svůj vlastní podgraf.
Výhody vnořených grafů: izolace tras uvnitř modulu, jednotný back stack pro skupinu obrazovek, možnost navigace podle prefixu bez odhalení vnitřní struktury. Například graf „auth" obsahuje „auth/login" a „auth/register". Navigace je možná jak po plné trase, tak po prefixu s přesměrováním na startDestination.
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 podporují předávání argumentů na úrovni grafu: parametry deklarované v route grafu se předávají do všech vnitřních tras. Pro vyčištění vnořeného grafu použijte popBackStack(route) — odstraní všechny vnitřní záznamy. Vnořené grafy nemají omezení hloubky, ale pro čitelnost se doporučuje maximálně 3 úrovně.
NavHost podporuje animaci přechodů mezi composable trasami pomocí parametrů enterTransition, exitTransition, popEnterTransition a popExitTransition. Animace se definují jednou pro NavHost a aplikují na všechny trasy, nebo individuálně pro každý composable. Ve výchozím nastavení je animace vypnutá.
Typická konfigurace: enterTransition = slideInHorizontally(initialOffsetX = { it }) — obrazovka vjíždí zprava; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — obrazovka odjíždí doleva. Pro pop animaci jsou směry zrcadlové: obrazovka vjíždí zleva a odjíždí doprava. Pro BottomNavigation se používá fadeIn/fadeOut bez slidu.
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 */ }
Vlastní animace se vytvářejí pomocí Compose Animation API: AnimatedContentTransitionScope poskytuje přístup k rozměrům kontejneru, průběhu animace a direction. Pro shared element transition (jeden prvek plynule přechází na jinou obrazovku) je vyžadována knihovna Accompanist Navigation Animation nebo vlastní implementace pomocí sharedElement Modifier. Podle Android Developers (2025) se výchozí slide animace (vjezd zprava, odjezd doleva) používá v 80% Android aplikací s navigací.
Často kladené otázky
Technicky ano, ale nedoporučuje se. Každý NavHost vytváří nezávislý back stack, což narušuje jednotnou navigaci. Výjimkou jsou oddělené oblasti, například NavHost pro hlavní obsah a NavHost pro BottomSheet s vlastní navigací.
NavHost — navigační kontejner přepínající obrazovky. Scaffold — rozvržení celé stránky (TopAppBar, BottomNavigation, FloatingActionButton). Obvykle je NavHost umístěn uvnitř Scaffold.content. Scaffold neřídí navigaci, pouze poskytuje sloty pro UI komponenty.
ViewModel se vytváří v rámci NavBackStackEntry pomocí viewModel(). Pro sdílení ViewModel mezi obrazovkami použijte parentNavController: připojte sdílený ViewModel k nadřazenému entry. Alternativa — DI (Hilt/Koin) s rozsahem NavGraph.
To je normální chování — NavHost odstraňuje composable z kompozice při opuštění trasy. Pro zachování stavu použijte rememberSaveable pro UI stav a ViewModel se SavedStateHandle pro business logiku.
Přidejte poslední trasu composable("404") a navigaci na ni při neznámém deep link. V NavHost neexistuje catch-all trasa — zkontrolujte trasu v intent handleru Deep Link před navigate(). Pokud route nebyl nalezen — navigujte na 404.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také