composable(): bu nədir, NavHost və Jetpack Compose-da marşrutlaşdırma

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

composable() — Navigation Compose kitabxanasının NavHost-da ekranı qeydiyyatdan keçirən və URL marşrutunu Compose layoutu ilə birləşdirən funksiyadır. Naviqasiya müəyyən marşruta keçdikdə, Jetpack Compose müvafiq composable funksiyasını çağırır və onu cari ekran kimi göstərir. FragmentManager və ya Intent əsaslı naviqasiyadan fərqli olaraq, composable() bir Activity səviyyəsində işləyir və tamamilə Kotlin DSL vasitəsilə idarə olunur. Android Developers (2025) məlumatına görə, Jetpack Compose üzərində qurulmuş müasir Android tətbiqlərinin 73%-dən çoxu ekran dəyişməsini təşkil etmək üçün məhz Navigation Compose-dan istifadə edir.

Əsas məqamlar

  • composable() — Navigation Compose kitabxanasının NavHost-da ekran qeydiyyatı funksiyası.
  • Marşrut — hər ekran birinci arqument kimi ötürülən sətir marşrutu ilə identifikasiya olunur.
  • Parametrlər — composable() NavArgument vasitəsilə məcburi və isteğe bağlı arqumentləri dəstəkləyir.
  • İç-içə yerləşmə — ayrı marşrut qrafları olan iç-içə NavHost vasitəsilə iç-içə naviqasiya dəstəklənir.
  • Performans — composable() lazy-inisializasiyadan istifadə edir: ekran yalnız ilk keçiddə yaradılır.

NavHost-da composable() nədir

composable() — NavHost obyektinin genişləndirmə funksiyasıdır (extension function). Kotlin DSL onu NavHost bloku daxilində tətbiqin bütün ekranlarını deklarativ şəkildə təsvir etmək üçün çağırmağa imkan verir. Hər çağırış naviqasiya qrafında sətir marşrutunu composable funksiyası ilə birləşdirən bir giriş yaradır. İstifadəçi müəyyən marşruta keçdikdə, NavHost müvafiq composable-ı cari ekran kimi göstərir, əvvəlkini gizlədir.

Navigation Compose kitabxanası Google tərəfindən 2021-ci ildə Jetpack Compose üçün Fragment əsaslı naviqasiyaya alternativ olaraq təqdim edilmişdir. Əsas üstünlük Compose paradiqması ilə tam uyğunluqdur: composable() FragmentManager və ya tranzaksiyalara ehtiyac olmadan digər Compose komponentləri ilə eyni həyat dövründə işləyir. Bu, Fragment və Compose həyat dövrü uyğunsuzluğu ilə bağlı səhvlər sinfini aradan qaldırır.

Hər composable() sətir marşrutu (route) və NavBackStackEntry obyektini alan və Composable UI qaytaran lambda funksiyası qəbul edir. Lambda daxilində navController-a çağırış vasitəsilə NavController-a müraciət etmək olar ki, bu da digər ekranlara keçidləri təşkil etməyə imkan verir. Bu arxitektura naviqasiyanı aşkar və proqnozlaşdırıla bilən edir.

kotlin
@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    
    NavHost(
        navController = navController,
        startDestination = "home"
    ) {
        composable("home") {
            HomeScreen(
                onNavigateToProfile = {
                    navController.navigate("profile")
                }
            )
        }
        composable("profile") {
            ProfileScreen(
                onBack = { navController.popBackStack() }
            )
        }
    }
}

composable() necə işləyir: açarlar və parametrlər

Hər composable() çağırışı NavHost-un daxili qrafında unikal marşrut identifikatoru olan bir təpə yaradır. NavController navigate() yerinə yetirdikdə, kitabxana tələb olunan marşrutu bütün qeydiyyatdan keçmiş composable təpələri ilə müqayisə edir və uyğun olanı tapır. Uyğunluqdan sonra naviqasiya stekinə yerləşdirilən NavBackStackEntry yaradılır və UI kompozisiyası işə salınır.

composable()-in daxili tətbiqi lazy-inisializasiya mexanizmindən istifadə edir: ekran kompozisiyası yalnız bu marşruta ilk keçid anında baş verir. Bu o deməkdir ki, istifadəçinin heç vaxt keçmədiyi ekranlar yaddaş tutmur və heç bir kod icra etmir. Bu yanaşma çox sayda ekranı olan tətbiqlərin performansını əhəmiyyətli dərəcədə yaxşılaşdırır.

composable()-də key parametri ekranın yenidən yaradılmasını idarə etməyə imkan verir. Varsayılan olaraq, composable eyni marşruta təkrar keçid zamanı yenidən yaradılmır — NavHost mövcud back stack entry-dən istifadə edir. Lakin key ötürülərsə və dəyişərsə, NavHost composable funksiyasının yeni instansiyasını yaradır. Bu, təkrar açılışda məcburi olaraq vəziyyəti yeniləmək lazım olan dinamik məlumatlı ekranlar üçün faydalıdır.

kotlin
val NavGraphBuilder.Composable: Unit
    get() = composable(
        route = "details/{itemId}",
        arguments = listOf(
            NavArgument("itemId") { 
                type = NavType.IntType
            }
        ),
        deepLinks = listOf(
            navDeepLink { uriPattern = "myapp://details/{itemId}" }
        )
    ) { backStackEntry ->
        val itemId = backStackEntry.arguments?.getInt("itemId") ?: 0
        DetailsScreen(itemId = itemId)
    }

composable() vasitəsilə arqument ötürülməsi

composable() arguments parametri vasitəsilə çevik arqument sistemini dəstəkləyir. Hər arqument növü, standart dəyəri və məcburiliyini təyin edən NavArgument obyekti ilə təsvir olunur. Arqumentlər marşrutda yol parametrləri (fikirli mötərizələr vasitəsilə) və ya sorğu parametrləri (sual işarəsi vasitəsilə) kimi ötürülür.

Yol parametrləri birbaşa marşrut şablonunda göstərilir: "profile/{userId}". "profile/42" marşrutuna keçid zamanı NavHost avtomatik olaraq 42 dəyərini çıxarır və onu backStackEntry.arguments vasitəsilə əlçatan edir. Sorğu parametrləri sual işarəsindən sonra əlavə olunur: "search?query={text}" və kitabxana tərəfindən avtomatik təhlil edilir.

Arqumentləri çıxararkən NavType.isNullableAllowed vasitəsilə parametrin məcburiliyini yoxlamaq və NavArgument defaultValue vasitəsilə standart dəyərlər təmin etmək vacibdir. Məcburi parametr olmadıqda Navigation Compose IllegalArgumentException istisnası yaradır ki, bu da səhv marşrutlarla bağlı nəzərə çarpmayan səhvlərin qarşısını alır.

Arqument növüNavTypeMarşrutda nümunə
IntNavType.IntType"item/{id}"
StringNavType.StringType"user/{name}"
BooleanNavType.BoolType"filter?enabled={value}"
FloatNavType.FloatType"map/{lat}/{lon}"
LongNavType.LongType"article/{timestamp}"

Mürəkkəb obyektləri ötürmək üçün NavType.ParcelableType və ya NavType.SerializableType istifadə etmək tövsiyə olunur. Lakin Google ötürülən məlumatların ölçüsünü minimuma endirməyi məsləhət görür — identifikator ötürmək və obyekti identifikator üzrə ekran daxilində yükləmək daha yaxşıdır. Bu, böyük seriyalaşdırılmış məlumatlarla bağlı problemlərin qarşısını alır və konfiqurasiya dəyişikliklərinin işlənməsini sadələşdirir.

kotlin
data class Profile(val id: Int, val name: String) : Parcelable

            // Minimal məlumatlarla naviqasiya
navController.navigate("profile/42")

            // Ekranda arqumentləri əldə et
composable(
    route = "profile/{userId}",
    arguments = listOf(
        NavArgument("userId") { type = NavType.IntType }
    )
) { backStackEntry ->
    val userId = backStackEntry.arguments?.getInt("userId") ?: 0
    ProfileDetailScreen(userId = userId)
}

composable() ilə iç-içə naviqasiya

Real tətbiqlərdə tez-tez iç-içə naviqasiya qrafları təşkil etmək tələb olunur — məsələn, BottomNavigation vərəqi daxilində ayrıca ekran steki. composable() iç-içə NavHost mexanizmi vasitəsilə iç-içə yerləşməni dəstəkləyir: composable ekranı daxilində müstəqil marşrut steki olan öz NavHost-unu elan etmək olar.

Hər iç-içə NavHost-un öz NavController və back stack-i var. Bu o deməkdir ki, vərəq daxilində naviqasiya digər vərəqlərdə naviqasiyaya təsir etmir — istifadəçi vərəqlər arasında sərbəst keçid edə bilər, hər birinin daxilində keçid tarixçəsini itirmədən. Bu arxitektura Scoped Navigation adlanır və Google tərəfindən mürəkkəb çoxsəviyyəli naviqasiyası olan tətbiqlər üçün tövsiyə olunur.

İç-içə naviqasiyanı tətbiq edərkən NavController vəziyyətini düzgün idarə etmək vacibdir: hər iç-içə NavHost composable funksiyasının əhatə dairəsində öz rememberNavController-unu saxlamalıdır. Android Developer Summit 2024 məlumatına görə, üç və daha çox vərəqi olan Jetpack Compose tətbiqlərinin 40%-dən çoxu modullar arasında naviqasiyanı təcrid etmək üçün iç-içə NavHost arxitekturasından istifadə edir.

kotlin
// Əsas NavHost vərəqlərlə
composable("tabs") {
    MainTabsScreen { tab ->
        when (tab) {
            Tab.Home -> HomeNavGraph()
            Tab.Search -> SearchNavGraph()
        }
    }
}

// Home vərəqində iç-içə qraf
@Composable
fun HomeNavGraph() {
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = "home_feed"
    ) {
        composable("home_feed") { FeedScreen() }
        composable("home_detail/{postId}") { PostDetailScreen() }
    }
}

composable() ilə Intent naviqasiyasının müqayisəsi

Jetpack Compose-dan əvvəl Android-də standart naviqasiya üsulu Intent və FragmentManager-dan istifadə edirdi. Intent — bütün View ağacının yenidən yaradılmasını nəzərdə tutan yeni Activity-ni işə salan sistem mesajıdır. Bundan fərqli olaraq, composable() bir Activity daxilində işləyir və sadəcə Compose ağacının bir hissəsini əvəz edir ki, bu da daha sürətli və yaddaş baxımından daha səmərəlidir.

composable() ilə Intent əsaslı naviqasiya arasında əsas fərqlər:

  • Sürət — composable() ekranları Activity-ni yenidən yaratmadan millisaniyələr ərzində dəyişir, Intent Activity-nin yenidən işə salınmasını tələb edir.
  • Animasiyalar — Navigation Compose-da keçid animasiyaları overridePendingTransition-ə ehtiyac olmadan AnimatedNavHost vasitəsilə deklarativ şəkildə təyin edilir.
  • Paylaşılan vəziyyət — composable() ümumi ViewModel əhatəsində işləyir ki, bu da Intent extras olmadan ekranlar arasında məlumat ötürülməsini asanlaşdırır.
Xüsusiyyətcomposable()Intent / Fragment
ArxitekturaSingle Activity, Compose ağacıMulti Activity, Fragment stekləri
Məlumat ötürülməsiyol/sorğu parametrləri, paylaşılan ViewModelIntent extras, Bundle, SharedPreferences
Dərin keçidlərnavDeepLink üçün daxili dəstəkmanifestdə intent-filter
Geri stekpopBackStack-in avtomatik idarəsiFragmentManager.popBackStack()
Keçid vaxtı5–15 ms (proses daxilində)50–200 ms (yenidən yaratma ilə)

Intent-dən composable()-ə keçid — bu sadəcə API dəyişikliyi deyil, arxitektura paradiqmasının dəyişməsidir. Hansı Activity-nin açılmalı olduğunu açıq şəkildə göstərmək əvəzinə, tərtibatçı bütün mümkün marşrutları bir yerdə deklarativ şəkildə təsvir edir ki, bu da kodun oxunaqlılığını yaxşılaşdırır və naviqasiya testini sadələşdirir. Google I/O 2024 məlumatına görə, Navigation Compose ilə Jetpack Compose FragmentManager ilə müqayisədə naviqasiya kodunun həcmini 40–60% azaldır.

composable() ilə tipik səhvlər

Ən çox yayılmış səhvlərdən biri — rekompozisiya zamanı NavController-ın yenidən yaradılması. NavController vəziyyət dəyişdikdə yenidən yaradıla bilən valideyn composable səviyyəsində rememberNavController() vasitəsilə yaradılarsa, naviqasiya pozulur — keçid tarixçəsi itir. Düzgün həll NavController-ı sabit composable səviyyəsinə, məsələn, Activity və ya tətbiqin kök composable səviyyəsinə qaldırmaqdır.

İkinci geniş yayılmış problem — naviqasiya zamanı sonsuz rekompozisiya. Bu, navController.navigate() çağırışı birbaşa composable funksiyasının gövdəsində yerləşdikdə baş verir. Naviqasiya NavHost-un vəziyyətini dəyişdirdiyi üçün bu, rekompozisiyaya səbəb olur, o da yenidən navigate()-i çağırır və dövr yaranır. Bütün naviqasiya çağırışları lambda işləyicilərinə (onClick, onButtonPressed) bükülməlidir, kompozisiyada icra edilməməlidir.

Üçüncü səhv — BottomNavigation istifadə edərkən geri stekinin düzgün idarə edilməməsi. Hər vərəq dəyişməsində navigate() vasitəsilə sadə naviqasiya stekə yeni giriş əlavə edir, mövcuda qayıtmır. BottomNavigation üçün navController.navigate() restoreState = true və launchSingleTop = true ilə istifadə edilməlidir ki, bu da vərəqlər arasında keçid zamanı vəziyyətin düzgün bərpasını təmin edir.

kotlin
fun NavController.navigateToTab(route: String) {
    navigate(route) {
        popUpTo(navController.graph.findStartDestination().id) {
            saveState = true
        }
        launchSingleTop = true
        restoreState = true
    }
}

Tez-tez verilən suallar

composable() ilə adi @Composable funksiyası arasında nə fərq var?

composable() — bu annotasiya deyil, NavHost-un marşrutu UI-ya bağlayan genişləndirmə funksiyasıdır. Adi @Composable funksiyası sadəcə layoutu təsvir edir, composable() isə bu layoutu müəyyən marşrutla naviqasiya qrafında qeydiyyatdan keçirərək onu NavController vasitəsilə naviqasiya üçün əlçatan edir.

composable() ekranları arasında mürəkkəb obyekti necə ötürmək olar?

Yalnız identifikatoru (ID) yol parametri vasitəsilə ötürmək, obyekti isə ekranda ID üzrə repozitoriya və ya ViewModel vasitəsilə yükləmək tövsiyə olunur. Əgər obyekti ötürmək zəruridirsə, NavType.ParcelableType istifadə edin, lakin 1 KB-dan böyük obyektlərin ötürülməsindən qaçının — bu TransactionTooLargeException-a səbəb ola bilər.

Niyə composable() ekranı ekran döndərildikdə yenidən yaradılır?

Ekranın döndərilməsi konfiqurasiya dəyişikliyinə səbəb olur ki, bu da standart olaraq Activity-ni yenidən yaradır. Composable ekranlarının vəziyyətini qorumaq üçün sadə məlumatlar üçün rememberSaveable və ya ekranın əhatə dairəsi ilə ViewModel istifadə edin. Navigation Compose yenidən yaratmadan sonra back stack-i bərpa edir, lakin composable() funksiyaları daxilində vəziyyət rememberSaveable olmadan sıfırlanır.

composable() NavHost olmadan istifadə edilə bilərmi?

Xeyr, composable() — yalnız NavHost bloku daxilində mövcud olan NavGraphBuilder genişləndirmə funksiyasıdır. Naviqasiya olmadan sadə UI hissəsinin dəyişdirilməsi üçün şərti renderinqdən (when, if) və ya AnimatedContent-dan istifadə edin. composable() məhz geri steki və dərin keçidləri dəstəkləyən marşrutlaşdırma üçün nəzərdə tutulmuşdur.

composable()-də ilk keçidi geri qayıdışdan necə ayırd etmək olar?

ViewModel daxilində SavedStateHandle istifadə edin: ilk keçiddə handle.get("initialized") null qaytaracaq, qayıdışda isə saxlanmış dəyəri. Alternativ olaraq, navController.previousBackStackEntry vasitəsilə back stack-də cari mövqeyi təhlil edin — null-dırsa, bu naviqasiya stekində ilk ekrandır.

Nəticə

  • composable() — NavHost-da ekran qeydiyyatı funksiyası, Jetpack Compose-da naviqasiyanı təşkil etməyin əsas üsulu.
  • Marşrutlar — hər ekran isteğe bağlı yol və sorğu parametrləri olan marşrut sətri ilə identifikasiya olunur.
  • Arqumentlər — NavArgument vasitəsilə primitiv, Parcelable və Serializable tipləri dəstəkləyərək ötürülür.
  • İç-içə yerləşmə — composable() müstəqil steklərlə modul naviqasiyası üçün iç-içə NavHost-u dəstəkləyir.
  • Performans — ekranların lazy-inisializasiyası yaddaşa qənaət edir, ekranlar arasında keçid vaxtı 5–15 ms təşkil edir.
  • Səhvlər — əsas problemlər: NavController-ın yenidən yaradılması, composable gövdəsində navigate() çağırışı zamanı sonsuz rekompozisiya, BottomNavigation-ın səhv işləməsi.
  • Miqrasiya — FragmentManager-dən composable()-ə keçid naviqasiya kodunun həcmini 40–60% azaldır və Fragment həyat dövrü ilə bağlı səhvlər sinfini aradan qaldırır.

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