NavHost — ano ito, pagbuo ng graph at mga ruta sa Jetpack Compose

May-akda: IT Sectr Nai-publish: 2026-06-30 Oras ng pagbabasa: 7 min

Ang NavHost ay isang composable container na nagsisilbing entry point para sa navigation graph sa Jetpack Compose. Pinag-uugnay nito ang NavController sa isang set ng mga ruta at nagre-render ng kasalukuyang screen batay sa estado ng back stack. Ayon sa Android Developers (2025), ang NavHost ay isang mandatoryong component para sa anumang Compose app na may navigation. Sa loob ng NavHost, nagrerehistro ng mga composable na ruta na may opsyonal na argumento, deep links, at animation. Ang bawat ruta ay isang ordinaryong composable function na tumatanggap ng NavBackStackEntry na may data ng transition. Awtomatikong hinahawakan ng NavHost ang back press, pag-save ng estado, at pag-restore sa reconfiguration.

Mga Pangunahing Punto

  • NavHost — composable container na nag-uugnay ng NavController sa graph ng mga ruta at nagre-render ng kasalukuyang screen
  • composable() — function para magrehistro ng ruta na may route, argumento, deep links, at transition animation
  • startDestination — panimulang ruta na binubuksan kapag ginawa ang NavHost
  • Mga Argumento ay tinutukoy sa pamamagitan ng navArgument na may NavType para sa naka-type na pagpapadala ng data sa pagitan ng mga screen
  • Animation ay naka-configure nang global o indibidwal sa pamamagitan ng enterTransition, exitTransition parameters

Ano ang NavHost sa Jetpack Compose?

NavHost ay isang composable function na nagbibigay ng container para sa pagpapakita ng kasalukuyang navigation screen. Ang NavHost ay tumatanggap ng NavController, startDestination, at graph ng mga ruta na binuo sa pamamagitan ng Kotlin DSL. Kapag nagbago ang kasalukuyang ruta, inililipat ng NavHost ang ipinapakitang composable na may tinukoy na animation.

Ang NavHost ay gumagana bilang tagapaglipat ng screen: sinusubaybayan nito ang kasalukuyang NavBackStackEntry mula sa NavController at nagre-render ng kaukulang composable block. Ang bawat screen ay isang independiyenteng composable function na tumatanggap ng NavBackStackEntry na may mga argumento ng ruta. Lahat ng screen ay umiiral sa iisang composition tree, ngunit ang NavHost ay nagpapakita lamang ng isa sa isang pagkakataon, na itinatago ang iba sa pamamagitan ng animation.

Hindi tulad ng FragmentManager, ang NavHost ay hindi gumagawa ng Fragment para sa bawat screen. Ang buong lifecycle ay pinamamahalaan sa pamamagitan ng CompositionLifecycle — ang mga composable function ay walang onStart/onResume, kaya para sa side-effects ay ginagamit ang LaunchedEffect at DisposableEffect. Awtomatikong nag-subscribe ang NavHost sa NavController at nag-recompose ng UI kapag nagbago ang ruta.

Ayon sa Google, ang NavHost ay stable na API mula noong Navigation 2.4.0. Mula sa bersyon 2.8.0, sinusuportahan ng NavHost ang Type-Safe Navigation sa pamamagitan ng Kotlin Serialization, na pumapalit sa string route ng mga data class. Sinusuportahan din ng NavHost ang mga nested graph, na nagpapahintulot sa pag-oorganisa ng navigation ayon sa module.

Ang NavHost ay ginawa gamit ang dalawang mandatoryong parameter: navController (instance ng NavHostController) at startDestination (string ng ruta ng unang screen). Ang ikatlong parameter — builder block, kung saan nagrerehistro ng lahat ng ruta sa pamamagitan ng composable(), navigation(), at dialog().

kotlin
@Composable
fun AppNavHost(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") { HomeScreen(navController) }
        composable("settings") { SettingsScreen(navController) }
    }
}

Ang startDestination ay ang rutang binubuksan sa unang pagtakbo ng NavHost. Kung walang laman ang back stack, awtomatikong idaragdag ng NavHost ang startDestination sa stack. Sa reconfiguration (pag-ikot ng screen), ire-restore ng NavHost ang huling ruta mula sa savedState, hindi ang startDestination.

Para sa BottomNavigation, ang startDestination ay isa sa mga ruta ng ibabang panel. Ang iba pang ruta ng panel ay idinaragdag bilang hiwalay na composable entries. Ang NavHost ay dapat ilagay sa loob ng Scaffold.content — kung saan ipinapakita ang pangunahing nilalaman ng app. Sinasakop ng NavHost ang lahat ng magagamit na taas minus TopAppBar at BottomNavigation.

Pagrehistro ng mga ruta sa pamamagitan ng composable

Ang function na composable(route, arguments, deepLinks, enterTransition, exitTransition, content) ay nagrerehistro ng ruta sa graph ng NavHost. Ang parameter na route ay isang string na naglalarawan ng landas na may opsyonal na placeholder sa anyong {paramName}. Ang placeholder ay pinapalitan ng konkretong halaga sa navigation.

Ang content block ay tumatanggap ng NavBackStackEntry kung saan kinukuha ang mga argumento. Ang composable function ng screen ay nire-render lamang kapag ang kasalukuyang ruta ng NavController ay tugma sa route. Kapag hindi tugma, ang composable ay aalisin mula sa composition, ngunit ang estado nito ay maaaring i-save sa pamamagitan ng rememberSaveable o ViewModel na may SavedStateHandle.

kotlin
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)
}

Ang bilang ng composable entries sa loob ng NavHost ay maaaring kahit ano — mula ilan hanggang daan-daan. Para sa malalaking app, ang mga ruta ay hinahati ayon sa module at ikinokonekta sa pamamagitan ng mga nested graph. Ang bawat composable ay maaaring magkaroon ng sariling animation, deep links, at argument settings.

Mga Argumento at naka-type na parameter ng ruta

Ang mga argumento ng ruta ay tinutukoy sa pamamagitan ng parameter na arguments: List<NamedNavArgument> sa composable(). Ang bawat argumento ay tinutukoy sa pamamagitan ng navArgument(name) { type; defaultValue }. Tinutukoy ng NavType ang uri ng argumento: StringType, IntType, LongType, FloatType, BoolType, ParcelableType, at ReferenceType.

Parameter ng RutaHalimbawa ng routeNavType
Landas (path)"user/{id}"NavType.IntType
Query"search?q={query}"NavType.StringType
Opsyonal"details/{id}?tab={tab}"StringType + defaultValue=""
Parcelable"checkout/{order}"NavType.ParcelableType

Ang mga argumento ay kinukuha mula sa NavBackStackEntry sa pamamagitan ng arguments?.getInt("id"). Para sa mga mandatoryong argumento, ang defaultValue ay maaaring wala — ang NavType ay gagamit ng null. Para sa mga opsyonal na argumento, ang defaultValue ay kinakailangan, kung hindi ang navigation ay magtathrow ng exception kapag wala ang parameter.

Mula noong Navigation 2.8.0, inirerekomenda ang Type-Safe Navigation: tukuyin ang sealed class o data class para sa mga ruta na may Kotlin Serialization. Sa halip na string route, gamitin ang composable<RouteType> { backStackEntry -> }. Tinatanggal nito ang mga typo sa route at awtomatikong bumubuo ng NavType para sa mga argumento. Para sa migration, idagdag ang dependency na navigation-compose-typesafe at ang Kotlin Serialization plugin.

Mga nested navigation graph

nested graphs — mekanismo ng pagpapangkat ng mga ruta sa loob ng NavHost sa pamamagitan ng function na navigation(route, startDestination). Ang isang nested graph ay may sariling route prefix at startDestination, at lahat ng ruta nito ay naa-access sa pamamagitan ng prefix. Ang nested graphs ay ginagamit para sa modular architecture, kung saan ang bawat feature module ay nagrerehistro ng sarili nitong subgraph.

Mga bentahe ng nested graphs: paghihiwalay ng mga ruta sa loob ng module, pare-parehong back stack para sa grupo ng mga screen, kakayahang mag-navigate ayon sa prefix nang hindi inilalantad ang panloob na istraktura. Halimbawa, ang graph na "auth" ay naglalaman ng "auth/login" at "auth/register". Ang navigation ay posible kapwa sa buong ruta at sa pamamagitan ng prefix na may redirect sa startDestination.

kotlin
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) }
    }
}

Sinusuportahan ng nested graphs ang pagpapadala ng mga argumento sa antas ng graph: ang mga parameter na idineklara sa route ng graph ay ipinapadala sa lahat ng panloob na ruta. Para linisin ang nested graph, gamitin ang popBackStack(route) — tatanggalin nito ang lahat ng panloob na entries. Ang nested graphs ay walang limitasyon sa lalim, ngunit inirerekomenda ang hindi hihigit sa 3 antas para sa pagiging madaling basahin.

Animation at pag-customize ng mga transition

Sinusuportahan ng NavHost ang animation ng transition sa pagitan ng mga composable na ruta sa pamamagitan ng mga parameter na enterTransition, exitTransition, popEnterTransition, at popExitTransition. Ang mga animation ay tinutukoy nang isang beses para sa NavHost at inilalapat sa lahat ng ruta, o indibidwal para sa bawat composable. Bilang default, ang animation ay naka-disable.

Karaniwang configuration: enterTransition = slideInHorizontally(initialOffsetX = { it }) — ang screen ay pumapasok mula sa kanan; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — ang screen ay lumalabas sa kaliwa. Para sa pop animation, ang mga direksyon ay baligtad: ang screen ay pumapasok mula sa kaliwa at lumalabas sa kanan. Para sa BottomNavigation, ginagamit ang fadeIn/fadeOut na walang slide.

kotlin
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 */ }

Ang mga custom na animation ay ginagawa sa pamamagitan ng Compose Animation API: Ang AnimatedContentTransitionScope ay nagbibigay ng access sa mga dimensyon ng container, progress ng animation, at direction. Para sa shared element transition (isang elemento na maayos na lumilipat sa ibang screen) ay kinakailangan ang Accompanist Navigation Animation library o custom na implementasyon sa pamamagitan ng sharedElement Modifier. Ayon sa Android Developers (2025), ang default na slide animation (pagpasok mula sa kanan, paglabas sa kaliwa) ay ginagamit sa 80% ng Android apps na may navigation.

Mga Madalas Itanong

Maaari bang gumamit ng maraming NavHost sa isang Activity?

Sa teknikal na paraan oo, ngunit hindi inirerekomenda. Ang bawat NavHost ay gumagawa ng independiyenteng back stack, na sumisira sa pinag-isang navigation. Exception — magkahiwalay na lugar, halimbawa NavHost para sa pangunahing nilalaman at NavHost para sa BottomSheet na may sariling navigation.

Ano ang pagkakaiba ng NavHost at Scaffold sa Compose?

NavHost — navigation container na naglilipat ng mga screen. Scaffold — layout ng buong page (TopAppBar, BottomNavigation, FloatingActionButton). Karaniwang inilalagay ang NavHost sa loob ng Scaffold.content. Ang Scaffold ay hindi namamahala ng navigation, nagbibigay lamang ito ng mga slot para sa UI components.

Paano magpasa ng ViewModel sa pagitan ng mga screen sa pamamagitan ng NavHost?

Ang ViewModel ay ginagawa sa loob ng NavBackStackEntry sa pamamagitan ng viewModel(). Para mag-share ng ViewModel sa pagitan ng mga screen, gamitin ang parentNavController: i-attach ang shared ViewModel sa parent entry. Alternatibo — DI (Hilt/Koin) na may scope sa NavGraph.

Bakit muling ginagawa ng NavHost ang composable sa bawat transition?

Ito ay normal na behavior — inaalis ng NavHost ang composable mula sa composition kapag aalis sa ruta. Para mapanatili ang estado, gamitin ang rememberSaveable para sa UI state at ViewModel na may SavedStateHandle para sa business logic.

Paano magdagdag ng 404 handling (hindi kilalang ruta) sa NavHost?

Idagdag ang huling ruta na composable("404") at navigation dito kapag hindi kilalang deep link. Walang catch-all route ang NavHost — suriin ang ruta sa Deep Link intent-handler bago ang navigate(). Kung hindi natagpuan ang route — mag-navigate sa 404.

Buod

  • NavHost — composable container ng Navigation Compose, nag-uugnay ng NavController sa graph ng mga ruta at nagre-render ng kasalukuyang screen
  • composable() nagrerehistro ng ruta na may route, argumento (NavType), deep links, at animation
  • startDestination — panimulang ruta na binubuksan sa unang pagtakbo ng NavHost
  • Mga Argumento ay ipinapadala sa pamamagitan ng {param} placeholder na may NavType para sa pag-type at defaultValue para sa opsyonal na parameter
  • Mga nested graph sa pamamagitan ng navigation() ay nagpapahintulot ng pagpapangkat ng mga ruta ayon sa module na may isolated na back stack
  • Animation ng transition ay naka-configure sa pamamagitan ng enterTransition/exitTransition gamit ang Compose Animation API
  • Awtomatikong hinahawakan ng NavHost ang back press, pag-save ng estado, at deep links nang walang karagdagang code

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din