NavHost — τι είναι, κατασκευή γράφου και διαδρομές στο Jetpack Compose

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-30 Χρόνος ανάγνωσης: 7 λεπ

Το NavHost είναι ένα κοντέινερ composable που χρησιμεύει ως σημείο εισόδου για τον γράφο πλοήγησης στο Jetpack Compose. Συνδέει το NavController με ένα σύνολο διαδρομών και αποδίδει την τρέχουσα οθόνη ανάλογα με την κατάσταση του back stack. Σύμφωνα με το Android Developers (2025), το NavHost είναι υποχρεωτικό στοιχείο για κάθε εφαρμογή Compose με πλοήγηση. Μέσα στο NavHost καταχωρούνται composable διαδρομές με προαιρετικά ορίσματα, deep links και κινούμενα γραφικά. Κάθε διαδρομή είναι μια συνηθισμένη composable συνάρτηση που λαμβάνει NavBackStackEntry με δεδομένα μετάβασης. Το NavHost χειρίζεται αυτόματα το back press, την αποθήκευση κατάστασης και την επαναφορά κατά την αναδιαμόρφωση.

Κύρια σημεία

  • NavHost — κοντέινερ composable που συνδέει το NavController με τον γράφο διαδρομών και αποδίδει την τρέχουσα οθόνη
  • composable() — συνάρτηση καταχώρησης διαδρομής με route, ορίσματα, deep links και κινούμενα γραφικά μετάβασης
  • startDestination — η αρχική διαδρομή που ανοίγει κατά τη δημιουργία του NavHost
  • Ορίσματα ορίζονται μέσω navArgument με NavType για τυποποιημένη μεταφορά δεδομένων μεταξύ οθονών
  • Κινούμενα γραφικά ρυθμίζονται καθολικά ή μεμονωμένα μέσω των παραμέτρων enterTransition, exitTransition

Τι είναι το NavHost στο Jetpack Compose;

NavHost είναι μια composable συνάρτηση που παρέχει ένα κοντέινερ για την εμφάνιση της τρέχουσας οθόνης πλοήγησης. Το NavHost δέχεται ένα NavController, startDestination και τον γράφο διαδρομών που δημιουργήθηκε μέσω Kotlin DSL. Κατά την αλλαγή της τρέχουσας διαδρομής, το NavHost αλλάζει το εμφανιζόμενο composable με την καθορισμένη κινούμενη εικόνα.

Το NavHost λειτουργεί ως διακόπτης οθονών: παρακολουθεί την τρέχουσα NavBackStackEntry από το NavController και αποδίδει το αντίστοιχο composable μπλοκ. Κάθε οθόνη είναι μια ανεξάρτητη composable συνάρτηση που λαμβάνει NavBackStackEntry με τα ορίσματα της διαδρομής. Όλες οι οθόνες υπάρχουν στο ίδιο δέντρο σύνθεσης, αλλά το NavHost εμφανίζει μόνο μία κάθε φορά, κρύβοντας τις υπόλοιπες μέσω κινούμενων γραφικών.

Σε αντίθεση με το FragmentManager, το NavHost δεν δημιουργεί Fragment για κάθε οθόνη. Ολόκληρος ο κύκλος ζωής διαχειρίζεται μέσω του CompositionLifecycle — οι composable συναρτήσεις δεν έχουν onStart/onResume, επομένως για παρενέργειες χρησιμοποιούνται τα LaunchedEffect και DisposableEffect. Το NavHost εγγράφεται αυτόματα στο NavController και ανασυνθέτει το UI κατά την αλλαγή διαδρομής.

Σύμφωνα με την Google, το NavHost είναι σταθερό API από την έκδοση Navigation 2.4.0. Από την έκδοση 2.8.0, το NavHost υποστηρίζει Type-Safe Navigation μέσω Kotlin Serialization, το οποίο αντικαθιστά τις string διαδρομές με data κλάσεις. Το NavHost υποστηρίζει επίσης ένθετους γράφους, επιτρέποντας την οργάνωση της πλοήγησης ανά ενότητα.

Το NavHost δημιουργείται με δύο υποχρεωτικές παραμέτρους: navController (στιγμιότυπο NavHostController) και startDestination (string της διαδρομής της πρώτης οθόνης). Η τρίτη παράμετρος — το μπλοκ builder, στο οποίο καταχωρούνται όλες οι διαδρομές μέσω composable(), navigation() και dialog().

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

Το startDestination είναι η διαδρομή που ανοίγει κατά την πρώτη εκκίνηση του NavHost. Εάν το back stack είναι κενό, το NavHost προσθέτει αυτόματα το startDestination στη στοίβα. Κατά την αναδιαμόρφωση (περιστροφή οθόνης), το NavHost επαναφέρει την τελευταία διαδρομή από το savedState, όχι το startDestination.

Για το BottomNavigation, το startDestination είναι μία από τις διαδρομές του κάτω πίνακα. Οι υπόλοιπες διαδρομές του πίνακα προστίθενται ως ξεχωριστές composable εγγραφές. Το NavHost πρέπει να τοποθετηθεί μέσα στο Scaffold.content — εκεί όπου εμφανίζεται το κύριο περιεχόμενο της εφαρμογής. Το NavHost καταλαμβάνει όλο το διαθέσιμο ύψος μείον TopAppBar και BottomNavigation.

Καταχώρηση διαδρομών μέσω composable

Η συνάρτηση composable(route, arguments, deepLinks, enterTransition, exitTransition, content) καταχωρεί μια διαδρομή στον γράφο του NavHost. Η παράμετρος route είναι ένα string που περιγράφει τη διαδρομή με προαιρετικά placeholders της μορφής {paramName}. Το placeholder αντικαθίσταται με συγκεκριμένη τιμή κατά την πλοήγηση.

Το μπλοκ content λαμβάνει NavBackStackEntry από το οποίο εξάγονται τα ορίσματα. Η composable συνάρτηση της οθόνης αποδίδεται μόνο όταν η τρέχουσα διαδρομή του NavController ταιριάζει με το route. Σε περίπτωση ασυμφωνίας, το composable αφαιρείται από τη σύνθεση, αλλά η κατάστασή του μπορεί να αποθηκευτεί μέσω rememberSaveable ή ViewModel με 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)
}

Ο αριθμός των composable εγγραφών μέσα στο NavHost μπορεί να είναι οποιοσδήποτε — από λίγες έως εκατοντάδες. Για μεγάλες εφαρμογές, οι διαδρομές χωρίζονται ανά ενότητα και συνδέονται μέσω ένθετων γράφων. Κάθε composable μπορεί να έχει τις δικές του ρυθμίσεις κινούμενων γραφικών, deep links και ορισμάτων.

Ορίσματα και τυποποιημένες παράμετροι διαδρομών

Τα ορίσματα διαδρομής ορίζονται μέσω της παραμέτρου arguments: List<NamedNavArgument> στο composable(). Κάθε όρισμα καθορίζεται μέσω navArgument(name) { type; defaultValue }. Το NavType καθορίζει τον τύπο ορίσματος: StringType, IntType, LongType, FloatType, BoolType, ParcelableType και ReferenceType.

Παράμετρος διαδρομήςΠαράδειγμα routeNavType
Διαδρομή (path)"user/{id}"NavType.IntType
Ερώτημα (query)"search?q={query}"NavType.StringType
Προαιρετικό"details/{id}?tab={tab}"StringType + defaultValue=""
Parcelable"checkout/{order}"NavType.ParcelableType

Τα ορίσματα εξάγονται από το NavBackStackEntry μέσω arguments?.getInt("id"). Για υποχρεωτικά ορίσματα, το defaultValue μπορεί να παραλειφθεί — το NavType θα χρησιμοποιήσει null. Για προαιρετικά ορίσματα, το defaultValue είναι υποχρεωτικό, διαφορετικά η πλοήγηση θα προκαλέσει εξαίρεση όταν λείπει η παράμετρος.

Από την έκδοση Navigation 2.8.0, συνιστάται το Type-Safe Navigation: ορίστε μια sealed class ή data class για διαδρομές με Kotlin Serialization. Αντί για string route, χρησιμοποιήστε composable<RouteType> { backStackEntry -> }. Αυτό εξαλείφει τα τυπογραφικά σφάλματα στο route και δημιουργεί αυτόματα NavType για ορίσματα. Για μετεγκατάσταση, προσθέστε την εξάρτηση navigation-compose-typesafe και το πρόσθετο Kotlin Serialization.

Ένθετοι γράφοι πλοήγησης

nested graphs — μηχανισμός ομαδοποίησης διαδρομών μέσα στο NavHost μέσω της συνάρτησης navigation(route, startDestination). Ένας ένθετος γράφος έχει το δικό του πρόθεμα route και startDestination, και όλες οι διαδρομές του είναι προσβάσιμες μέσω του προθέματος. Τα nested graphs χρησιμοποιούνται για αρθρωτή αρχιτεκτονική, όπου κάθε λειτουργική ενότητα καταχωρεί τον δικό της υπογράφο.

Πλεονεκτήματα ένθετων γράφων: απομόνωση διαδρομών εντός της ενότητας, ενιαίο back stack για ομάδα οθονών, δυνατότητα πλοήγησης με πρόθεμα χωρίς αποκάλυψη της εσωτερικής δομής. Για παράδειγμα, ο γράφος "auth" περιέχει "auth/login" και "auth/register". Η πλοήγηση είναι δυνατή τόσο μέσω της πλήρους διαδρομής όσο και μέσω προθέματος με ανακατεύθυνση στο 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) }
    }
}

Τα nested graphs υποστηρίζουν τη μετάδοση ορισμάτων σε επίπεδο γράφου: οι παράμετροι που δηλώνονται στο route του γράφου μεταδίδονται σε όλες τις εσωτερικές διαδρομές. Για εκκαθάριση ενός ένθετου γράφου, χρησιμοποιήστε popBackStack(route) — θα αφαιρέσει όλες τις εσωτερικές εγγραφές. Οι ένθετοι γράφοι δεν έχουν όριο βάθους, αλλά για αναγνωσιμότητα συνιστώνται το πολύ 3 επίπεδα.

Κινούμενα γραφικά και προσαρμογή μεταβάσεων

Το NavHost υποστηρίζει κινούμενα γραφικά μετάβασης μεταξύ composable διαδρομών μέσω των παραμέτρων enterTransition, exitTransition, popEnterTransition και popExitTransition. Τα κινούμενα γραφικά ορίζονται μία φορά για το NavHost και εφαρμόζονται σε όλες τις διαδρομές, ή μεμονωμένα για κάθε composable. Από προεπιλογή, τα κινούμενα γραφικά είναι απενεργοποιημένα.

Τυπική διαμόρφωση: enterTransition = slideInHorizontally(initialOffsetX = { it }) — η οθόνη εισέρχεται από τα δεξιά; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — η οθόνη εξέρχεται προς τα αριστερά. Για pop κινούμενα γραφικά, οι κατευθύνσεις είναι αντίστροφες: η οθόνη εισέρχεται από τα αριστερά και εξέρχεται προς τα δεξιά. Για BottomNavigation, χρησιμοποιείται fadeIn/fadeOut χωρίς ολίσθηση.

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

Προσαρμοσμένα κινούμενα γραφικά δημιουργούνται μέσω του Compose Animation API: το AnimatedContentTransitionScope παρέχει πρόσβαση στις διαστάσεις του κοντέινερ, την πρόοδο του κινούμενου γραφικού και την κατεύθυνση. Για shared element transition (ένα στοιχείο που μεταβαίνει ομαλά σε άλλη οθόνη) απαιτείται η βιβλιοθήκη Accompanist Navigation Animation ή προσαρμοσμένη υλοποίηση μέσω sharedElement Modifier. Σύμφωνα με το Android Developers (2025), το προεπιλεγμένο slide κινούμενο γραφικό (είσοδος από δεξιά, έξοδος προς αριστερά) χρησιμοποιείται στο 80% των εφαρμογών Android με πλοήγηση.

Συχνές Ερωτήσεις

Μπορούν να χρησιμοποιηθούν πολλαπλά NavHost σε ένα Activity;

Τεχνικά ναι, αλλά δεν συνιστάται. Κάθε NavHost δημιουργεί ανεξάρτητο back stack, το οποίο διαταράσσει την ενιαία πλοήγηση. Εξαίρεση — ξεχωριστές περιοχές, για παράδειγμα NavHost για το κύριο περιεχόμενο και NavHost για BottomSheet με δική του πλοήγηση.

Ποια είναι η διαφορά μεταξύ NavHost και Scaffold στο Compose;

NavHost — κοντέινερ πλοήγησης που αλλάζει οθόνες. Scaffold — διάταξη ολόκληρης της σελίδας (TopAppBar, BottomNavigation, FloatingActionButton). Συνήθως το NavHost τοποθετείται μέσα στο Scaffold.content. Το Scaffold δεν διαχειρίζεται την πλοήγηση, παρέχει μόνο υποδοχές για στοιχεία UI.

Πώς να μεταφέρω ViewModel μεταξύ οθονών μέσω NavHost;

Το ViewModel δημιουργείται στο πλαίσιο του NavBackStackEntry μέσω viewModel(). Για κοινή χρήση ViewModel μεταξύ οθονών, χρησιμοποιήστε parentNavController: συνδέστε το κοινόχρηστο ViewModel στη γονική εγγραφή. Εναλλακτικά — DI (Hilt/Koin) με εύρος NavGraph.

Γιατί το NavHost αναδημιουργεί το composable σε κάθε μετάβαση;

Αυτή είναι φυσιολογική συμπεριφορά — το NavHost αφαιρεί το composable από τη σύνθεση κατά την αποχώρηση από τη διαδρομή. Για διατήρηση της κατάστασης, χρησιμοποιήστε rememberSaveable για την κατάσταση UI και ViewModel με SavedStateHandle για την επιχειρηματική λογική.

Πώς να προσθέσω χειρισμό 404 (άγνωστη διαδρομή) στο NavHost;

Προσθέστε την τελευταία διαδρομή composable("404") και πλοήγηση σε αυτήν για άγνωστο deep link. Το NavHost δεν έχει catch-all διαδρομή — ελέγξτε τη διαδρομή στον χειριστή intent Deep Link πριν από το navigate(). Εάν το route δεν βρεθεί — μεταβείτε στο 404.

Σύνοψη

  • NavHost — composable κοντέινερ του Navigation Compose, που συνδέει το NavController με τον γράφο διαδρομών και αποδίδει την τρέχουσα οθόνη
  • composable() καταχωρεί διαδρομή με route, ορίσματα (NavType), deep links και κινούμενα γραφικά
  • startDestination — η αρχική διαδρομή που ανοίγει κατά την πρώτη εκκίνηση του NavHost
  • Ορίσματα μεταδίδονται μέσω placeholders {param} με NavType για τυποποίηση και defaultValue για προαιρετικές παραμέτρους
  • Ένθετοι γράφοι μέσω navigation() επιτρέπουν την ομαδοποίηση διαδρομών ανά ενότητα με απομονωμένο back stack
  • Κινούμενα γραφικά μεταβάσεων ρυθμίζονται μέσω enterTransition/exitTransition χρησιμοποιώντας Compose Animation API
  • Το NavHost χειρίζεται αυτόματα το back press, την αποθήκευση κατάστασης και τα deep links χωρίς πρόσθετο κώδικα

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης