composable(): NavHost اور Jetpack Compose میں روٹنگ

مصنف: IT Sectr اشاعت: 2026-06-30 مطالعے کا وقت: 9 منٹ

composable() Navigation Compose لائبریری کا ایک فنکشن ہے جو NavHost میں ایک اسکرین رجسٹر کرتا ہے اور URL روٹ کو Compose لے آؤٹ سے جوڑتا ہے۔ جب نیویگیشن کسی متعین روٹ پر جاتی ہے، Jetpack Compose متعلقہ composable فنکشن کو کال کرتا ہے اور اسے موجودہ اسکرین کے طور پر دکھاتا ہے۔ FragmentManager یا Intent پر مبنی نیویگیشن کے برعکس، composable() ایک واحد Activity کی سطح پر کام کرتا ہے اور مکمل طور پر Kotlin DSL کے ذریعے منظم ہوتا ہے۔ Android Developers (2025) کے مطابق، Jetpack Compose پر بنی 73% سے زیادہ جدید Android ایپلیکیشنز اسکرین ٹرانزیشن کے لیے Navigation Compose استعمال کرتی ہیں۔

اہم نکات

  • composable() Navigation Compose لائبریری کے NavHost میں اسکرین رجسٹر کرنے کا فنکشن ہے۔
  • روٹ — ہر اسکرین ایک سٹرنگ روٹ سے پہچانی جاتی ہے جو پہلے آرگیومینٹ کے طور پر پاس کیا جاتا ہے۔
  • پیرامیٹرز — composable() NavArgument کے ذریعے آرگیومینٹس کو سپورٹ کرتا ہے، جس میں لازمی اور اختیاری دونوں شامل ہیں۔
  • نیسٹنگ — علیحدہ روٹ گراف کے ساتھ نیسٹڈ NavHost کے ذریعے نیسٹڈ نیویگیشن سپورٹڈ ہے۔
  • کارکردگی — composable() سست ابتدا استعمال کرتا ہے: اسکرین صرف پہلی نیویگیشن پر بنتی ہے۔

NavHost میں composable() کیا ہے

composable() NavHost آبجیکٹ کا ایک ایکسٹینشن فنکشن ہے۔ Kotlin DSL اسے NavHost بلاک کے اندر کال کرکے ایپلیکیشن کی تمام اسکرینوں کو اعلانیہ طور پر بیان کرنے کی اجازت دیتا ہے۔ ہر کال نیویگیشن گراف میں ایک اندراج بناتی ہے، ایک سٹرنگ روٹ کو composable فنکشن سے جوڑتی ہے۔ جب صارف کسی مخصوص روٹ پر جاتا ہے، NavHost پچھلی اسکرین کو چھپاتے ہوئے متعلقہ composable کو موجودہ اسکرین کے طور پر دکھاتا ہے۔

Navigation Compose لائبریری Google نے 2021 میں Jetpack Compose کے لیے Fragment پر مبنی نیویگیشن کے متبادل کے طور پر متعارف کروائی تھی۔ بنیادی فائدہ Compose پیراڈائم کے ساتھ مکمل مطابقت ہے: composable() FragmentManager یا ٹرانزیکشنز کی ضرورت کے بغیر دیگر Compose اجزاء کی طرح اسی لائف سائیکل میں کام کرتا ہے۔ یہ Fragment اور Compose لائف سائیکل کی عدم مطابقت سے متعلق بگز کی ایک کلاس کو ختم کرتا ہے۔

ہر composable() ایک سٹرنگ روٹ اور ایک lambda فنکشن لیتا ہے جو NavBackStackEntry آبجیکٹ حاصل کرتا ہے اور Composable UI لوٹاتا ہے۔ lambda کے اندر، دائرہ کار سے navController کے ذریعے NavController تک رسائی حاصل کی جا سکتی ہے، جو دوسری اسکرینوں پر نیویگیشن کی اجازت دیتی ہے۔ یہ آرکیٹیکچر نیویگیشن کو واضح اور پیش قیاس بناتا ہے۔

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() کیسے کام کرتا ہے: کیز اور پیرامیٹرز

composable() کی ہر کال NavHost کے داخلی گراف میں ایک منفرد روٹ شناخت کنندہ کے ساتھ ایک ورٹیکس بناتی ہے۔ جب NavController navigate() کو انجام دیتا ہے، لائبریری درخواست کردہ روٹ کا تمام رجسٹرڈ composable ورٹیکس سے موازنہ کرتی ہے اور ایک مماثلت تلاش کرتی ہے۔ مماثلت کے بعد، ایک NavBackStackEntry بنایا جاتا ہے، نیویگیشن سٹیک پر رکھا جاتا ہے، اور UI کمپوزیشن شروع ہوتی ہے۔

composable() کا داخلی نفاذ ایک سست ابتدا میکانزم استعمال کرتا ہے: اسکرین کمپوزیشن صرف اس روٹ پر پہلی نیویگیشن پر ہوتی ہے۔ اس کا مطلب ہے کہ جن اسکرینوں پر صارف نے کبھی نیویگیٹ نہیں کیا وہ میموری نہیں گھیرتیں اور کوئی کوڈ نہیں چلاتیں۔ یہ نقطہ نظر بہت سی اسکرینوں والی ایپلیکیشنز میں کارکردگی کو نمایاں طور پر بہتر بناتا ہے۔

composable() میں key پیرامیٹر اسکرین کی دوبارہ تخلیق کو منظم کرنے کی اجازت دیتا ہے۔ ڈیفالٹ کے طور پر، ایک ہی روٹ پر بار بار نیویگیشن پر composable دوبارہ نہیں بنتا — NavHost موجودہ بیک سٹیک اندراج استعمال کرتا ہے۔ تاہم، اگر key پاس کیا جائے اور وہ بدل جائے، NavHost composable فنکشن کی ایک نئی مثال بنائے گا۔ یہ متحرک ڈیٹا والی اسکرینوں کے لیے مفید ہے جہاں دوبارہ کھولنے پر حالت کو زبردستی ریفریش کرنے کی ضرورت ہوتی ہے۔

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() کے ذریعے آرگیومینٹس پاس کرنا

composable() arguments پیرامیٹر کے ذریعے ایک لچکدار آرگیومینٹ سسٹم کو سپورٹ کرتا ہے۔ ہر آرگیومینٹ کو NavArgument آبجیکٹ کے ذریعے بیان کیا جاتا ہے جو قسم، ڈیفالٹ ویلیو اور لازمی ہونے کی وضاحت کرتا ہے۔ آرگیومینٹس روٹ میں پاتھ پیرامیٹرز (کرلی بریسز کے ذریعے) یا کوئری پیرامیٹرز (سوالیہ نشان کے ذریعے) کے طور پر پاس کیے جاتے ہیں۔

پاتھ پیرامیٹرز براہ راست روٹ ٹیمپلیٹ میں متعین کیے جاتے ہیں: "profile/{userId}"۔ "profile/42" پر نیویگیٹ کرتے وقت، NavHost خود بخود ویلیو 42 نکالتا ہے اور اسے backStackEntry.arguments کے ذریعے قابل رسائی بناتا ہے۔ کوئری پیرامیٹرز سوالیہ نشان کے بعد شامل کیے جاتے ہیں: "search?query={text}" اور لائبریری کے ذریعے خود بخود پارس کیے جاتے ہیں۔

آرگیومینٹس نکالتے وقت، NavType.isNullableAllowed کے ذریعے پیرامیٹر کی لازمی حیثیت کو چیک کرنا اور NavArgument defaultValue کے ذریعے ڈیفالٹ ویلیوز فراہم کرنا ضروری ہے۔ اگر کوئی لازمی پیرامیٹر غائب ہے، Navigation Compose IllegalArgumentException پھینکتا ہے، جو غلط روٹس کے ساتھ باریک بگز کو روکتا ہے۔

آرگیومینٹ کی قسمNavTypeروٹ میں مثال
IntNavType.IntType"item/{id}"
StringNavType.StringType"user/{name}"
BooleanNavType.BoolType"filter?enabled={value}"
FloatNavType.FloatType"map/{lat}/{lon}"
LongNavType.LongType"article/{timestamp}"

پیچیدہ آبجیکٹ پاس کرنے کے لیے، NavType.ParcelableType یا NavType.SerializableType استعمال کرنے کی سفارش کی جاتی ہے۔ تاہم، Google منتقل کردہ ڈیٹا کے سائز کو کم سے کم کرنے کا مشورہ دیتا ہے — ایک شناخت کنندہ پاس کرنا اور اسکرین کے اندر ID کے ذریعے آبجیکٹ لوڈ کرنا بہتر ہے۔ یہ بڑے سیریلائزڈ ڈیٹا کے ساتھ مسائل کو روکتا ہے اور کنفیگریشن تبدیلیوں کو سنبھالنے کو آسان بناتا ہے۔

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

            // کم سے کم ڈیٹا کے ساتھ نیویگیٹ کریں
navController.navigate("profile/42")

            // اسکرین پر آرگیومینٹس حاصل کریں
composable(
    route = "profile/{userId}",
    arguments = listOf(
        NavArgument("userId") { type = NavType.IntType }
    )
) { backStackEntry ->
    val userId = backStackEntry.arguments?.getInt("userId") ?: 0
    ProfileDetailScreen(userId = userId)
}

composable() کے ساتھ نیسٹڈ نیویگیشن

حقیقی ایپلیکیشنز میں، اکثر نیسٹڈ نیویگیشن گراف کو منظم کرنا ضروری ہوتا ہے — مثال کے طور پر، BottomNavigation ٹیب کے اندر ایک علیحدہ اسکرین سٹیک۔ composable() نیسٹڈ NavHost کے ذریعے نیسٹنگ کو سپورٹ کرتا ہے: ایک composable اسکرین کے اندر، آپ آزاد روٹ سٹیک کے ساتھ اپنا NavHost اعلان کر سکتے ہیں۔

ہر نیسٹڈ NavHost کا اپنا NavController اور بیک سٹیک ہوتا ہے۔ اس کا مطلب ہے کہ ایک ٹیب کے اندر نیویگیشن دوسرے ٹیبز میں نیویگیشن کو متاثر نہیں کرتی — صارف ہر ایک کے اندر نیویگیشن ہسٹری کھوئے بغیر ٹیبز کے درمیان آزادانہ طور پر سوئچ کر سکتا ہے۔ اس آرکیٹیکچر کو Scoped Navigation کہا جاتا ہے اور Google اسے پیچیدہ کثیر سطحی نیویگیشن والی ایپلیکیشنز کے لیے تجویز کرتا ہے۔

نیسٹڈ نیویگیشن کو لاگو کرتے وقت، NavController کی حالت کو درست طریقے سے منظم کرنا ضروری ہے: ہر نیسٹڈ NavHost کو composable فنکشن کے دائرہ کار میں اپنا rememberNavController محفوظ کرنا چاہیے۔ Android Developer Summit 2024 کے مطابق، تین یا زیادہ ٹیبز والی 40% سے زیادہ Jetpack Compose ایپلیکیشنز ماڈیولز کے درمیان نیویگیشن کو الگ کرنے کے لیے نیسٹڈ NavHost آرکیٹیکچر استعمال کرتی ہیں۔

kotlin
// ٹیبز کے ساتھ مرکزی NavHost
composable("tabs") {
    MainTabsScreen { tab ->
        when (tab) {
            Tab.Home -> HomeNavGraph()
            Tab.Search -> SearchNavGraph()
        }
    }
}

// ہوم ٹیب کے اندر نیسٹڈ گراف
@Composable
fun HomeNavGraph() {
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = "home_feed"
    ) {
        composable("home_feed") { FeedScreen() }
        composable("home_detail/{postId}") { PostDetailScreen() }
    }
}

composable() بمقابلہ Intent نیویگیشن

Jetpack Compose سے پہلے، Android میں نیویگیشن کا معیاری طریقہ Intent اور FragmentManager استعمال کرتا تھا۔ Intent ایک سسٹم پیغام ہے جو ایک نئی Activity شروع کرتا ہے، جس کا مطلب پورے View ٹری کی دوبارہ تخلیق ہے۔ اس کے برعکس، composable() ایک واحد Activity کے اندر کام کرتا ہے اور Compose ٹری کے ایک حصے کو تبدیل کرتا ہے، جو نمایاں طور پر تیز اور میموری میں زیادہ موثر ہے۔

composable() اور Intent پر مبنی نیویگیشن کے درمیان اہم فرق:

  • رفتار — composable() Activity کو دوبارہ بنائے بغیر ملی سیکنڈز میں اسکرین تبدیل کرتا ہے؛ Intent کو Activity دوبارہ شروع کرنے کی ضرورت ہوتی ہے۔
  • اینیمیشنز — Navigation Compose میں، ٹرانزیشن اینیمیشنز overridePendingTransition کی ضرورت کے بغیر AnimatedNavHost کے ذریعے اعلانیہ طور پر متعین کی جاتی ہیں۔
  • مشترکہ حالت — composable() ایک مشترکہ ViewModel دائرہ کار میں کام کرتا ہے، جو Intent extras کے بغیر اسکرینوں کے درمیان ڈیٹا کی منتقلی کو آسان بناتا ہے۔
خصوصیتcomposable()Intent / Fragment
آرکیٹیکچرواحد Activity، Compose ٹریکثیر Activity، Fragment سٹیک
ڈیٹا کی منتقلیپاتھ/کوئری پیرامیٹرز، مشترکہ ViewModelIntent extras، Bundle، SharedPreferences
ڈیپ لنکسبلٹ ان navDeepLink سپورٹمینی فیسٹ میں intent-filter
بیک سٹیکخودکار popBackStack نظم و نسقFragmentManager.popBackStack()
سوئچ کا وقت5–15 ms (عمل کے اندر)50–200 ms (دوبارہ تخلیق کے ساتھ)

Intent سے composable() پر سوئچ کرنا صرف API کی تبدیلی نہیں ہے، بلکہ آرکیٹیکچرل پیراڈائم میں تبدیلی ہے۔ یہ واضح طور پر بتانے کے بجائے کہ کون سی Activity کھلنی چاہیے، ڈیویلپر ایک جگہ تمام ممکنہ روٹس کو اعلانیہ طور پر بیان کرتا ہے، جس سے کوڈ پڑھنے کی اہلیت بہتر ہوتی ہے اور نیویگیشن ٹیسٹنگ آسان ہوتی ہے۔ Google I/O 2024 کے مطابق، Navigation Compose کے ساتھ Jetpack Compose FragmentManager کے مقابلے میں نیویگیشن کوڈ کو 40–60% تک کم کرتا ہے۔

composable() کے ساتھ عام غلطیاں

سب سے عام غلطیوں میں سے ایک دوبارہ کمپوزیشن کے دوران NavController کا دوبارہ بنانا ہے۔ اگر NavController پیرنٹ composable سطح پر rememberNavController() کے ذریعے بنایا جاتا ہے، جو حالت تبدیل ہونے پر دوبارہ بن سکتا ہے، نیویگیشن ٹوٹ جاتی ہے — ہسٹری کھو جاتی ہے۔ صحیح حل NavController کو ایک مستحکم composable سطح پر اٹھانا ہے، جیسے Activity کی سطح یا ایپلیکیشن کا روٹ composable۔

دوسرا عام مسئلہ نیویگیشن کے دوران لامتناہی دوبارہ کمپوزیشن ہے۔ یہ اس وقت ہوتا ہے جب navController.navigate() براہ راست composable فنکشن کے باڈی میں رکھا جاتا ہے۔ چونکہ نیویگیشن NavHost کی حالت کو تبدیل کرتی ہے، یہ دوبارہ کمپوزیشن کو متحرک کرتی ہے، جو دوبارہ navigate() کو کال کرتی ہے، ایک لوپ بناتی ہے۔ تمام نیویگیشن کالز کو lambda ہینڈلرز (onClick، onButtonPressed) میں لپیٹا جانا چاہیے، نہ کہ کمپوزیشن میں انجام دیا جانا چاہیے۔

تیسری غلطی BottomNavigation استعمال کرتے وقت غلط بیک سٹیک ہینڈلنگ ہے۔ ہر ٹیب سوئچ پر navigate() کے ذریعے سادہ نیویگیشن موجودہ میں واپس آنے کے بجائے سٹیک میں ایک نیا اندراج شامل کرتی ہے۔ BottomNavigation کے لیے، آپ کو restoreState = true اور launchSingleTop = true کے ساتھ navController.navigate() استعمال کرنا چاہیے، جو ٹیب سوئچ کرتے وقت حالت کی درست بحالی کو یقینی بناتا ہے۔

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

اکثر پوچھے گئے سوالات

composable() اور عام @Composable فنکشن میں کیا فرق ہے؟

composable() کوئی اینوٹیشن نہیں ہے، بلکہ NavHost کا ایک ایکسٹینشن فنکشن ہے جو روٹ کو UI سے باندھتا ہے۔ ایک عام @Composable فنکشن صرف لے آؤٹ کو بیان کرتا ہے، جبکہ composable() اس لے آؤٹ کو ایک متعین روٹ کے ساتھ نیویگیشن گراف میں رجسٹر کرتا ہے، اسے NavController کے ذریعے نیویگیشن کے لیے قابل رسائی بناتا ہے۔

composable() اسکرینوں کے درمیان ایک پیچیدہ آبجیکٹ کیسے پاس کریں؟

پاتھ پیرامیٹر کے ذریعے صرف ایک شناخت کنندہ (ID) پاس کرنے کی سفارش کی جاتی ہے، اور ریپوزٹری یا ViewModel کے ذریعے ID کے ذریعے اسکرین پر آبجیکٹ لوڈ کریں۔ اگر آپ کو اب بھی آبجیکٹ پاس کرنے کی ضرورت ہے، تو NavType.ParcelableType استعمال کریں، لیکن 1 KB سے بڑے آبجیکٹ پاس کرنے سے گریز کریں — یہ TransactionTooLargeException کا سبب بن سکتا ہے۔

اسکرین گھمانے پر composable() اسکرین دوبارہ کیوں بنتی ہے؟

اسکرین گھمانا ایک کنفیگریشن تبدیلی کا سبب بنتا ہے، جو ڈیفالٹ کے طور پر Activity کو دوبارہ بناتا ہے۔ composable اسکرینوں کی حالت کو محفوظ رکھنے کے لیے، سادہ ڈیٹا کے لیے rememberSaveable یا اس اسکرین کے دائرہ کار کے ساتھ ViewModel استعمال کریں۔ Navigation Compose دوبارہ تخلیق کے بعد بیک سٹیک کو بحال کرتا ہے، لیکن composable() فنکشنز کے اندر کی حالت rememberSaveable کے بغیر ری سیٹ ہو جاتی ہے۔

کیا NavHost کے بغیر composable() استعمال کیا جا سکتا ہے؟

نہیں، composable() NavGraphBuilder کا ایک ایکسٹینشن فنکشن ہے، جو صرف NavHost بلاک کے اندر دستیاب ہے۔ نیویگیشن کے بغیر سادہ UI تبدیلی کے لیے، مشروط رینڈرنگ (when، if) یا AnimatedContent استعمال کریں۔ composable() خاص طور پر بیک سٹیک اور ڈیپ لنک سپورٹ کے ساتھ روٹنگ کے لیے ڈیزائن کیا گیا ہے۔

composable() میں پہلی نیویگیشن کو واپسی نیویگیشن سے کیسے الگ کیا جائے؟

ViewModel کے اندر SavedStateHandle استعمال کریں: پہلی نیویگیشن پر، handle.get("initialized") null لوٹاتا ہے؛ واپسی نیویگیشن پر، یہ محفوظ کردہ ویلیو لوٹاتا ہے۔ متبادل طور پر، navController.previousBackStackEntry کے ذریعے بیک سٹیک میں موجودہ پوزیشن کا تجزیہ کریں — اگر یہ null ہے، تو یہ نیویگیشن سٹیک میں پہلی اسکرین ہے۔

خلاصہ

  • composable() NavHost میں اسکرین رجسٹریشن فنکشن ہے، Jetpack Compose میں نیویگیشن کو منظم کرنے کا بنیادی طریقہ۔
  • روٹس — ہر اسکرین اختیاری پاتھ اور کوئری پیرامیٹرز کے ساتھ ایک روٹ سٹرنگ سے پہچانی جاتی ہے۔
  • آرگیومینٹس — پریمیٹو، Parcelable اور Serializable اقسام کی حمایت کے ساتھ NavArgument کے ذریعے پاس کیے جاتے ہیں۔
  • نیسٹنگ — composable() آزاد سٹیک کے ساتھ ماڈیولر نیویگیشن کو منظم کرنے کے لیے نیسٹڈ NavHost کو سپورٹ کرتا ہے۔
  • کارکردگی — سست اسکرین ابتدا میموری بچاتی ہے، اسکرین سوئچنگ کی رفتار 5–15 ms ہے۔
  • غلطیاں — اہم مسائل: NavController کی دوبارہ تخلیق، composable باڈی میں navigate() کے ساتھ لامتناہی دوبارہ کمپوزیشن، غلط BottomNavigation ہینڈلنگ۔
  • منتقلی — FragmentManager سے composable() پر سوئچ کرنے سے نیویگیشن کوڈ کا حجم 40–60% کم ہو جاتا ہے اور Fragment لائف سائیکل سے متعلق بگز کی ایک کلاس ختم ہو جاتی ہے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں