NavHost হল একটি composable কন্টেইনার যা Jetpack Compose এ নেভিগেশন গ্রাফের জন্য প্রবেশ বিন্দু হিসেবে কাজ করে। এটি NavController কে রুটের একটি সেটের সাথে সংযুক্ত করে এবং ব্যাক স্ট্যাকের অবস্থার উপর ভিত্তি করে বর্তমান স্ক্রিন রেন্ডার করে। Android Developers (2025) অনুযায়ী, NavHost নেভিগেশন সহ যেকোনো Compose অ্যাপ্লিকেশনের জন্য একটি বাধ্যতামূলক উপাদান। NavHost এর ভিতরে, ঐচ্ছিক আর্গুমেন্ট, ডিপ লিঙ্ক এবং অ্যানিমেশন সহ composable রুট রেজিস্টার করা হয়। প্রতিটি রুট হল একটি সাধারণ composable ফাংশন যা ট্রানজিশন ডেটা সহ NavBackStackEntry গ্রহণ করে। NavHost স্বয়ংক্রিয়ভাবে ব্যাক প্রেস, অবস্থা সংরক্ষণ এবং পুনর্বিন্যাসের সময় পুনরুদ্ধার পরিচালনা করে।
মূল বিষয়
NavHost হল একটি composable ফাংশন যা বর্তমান নেভিগেশন স্ক্রিন প্রদর্শনের জন্য একটি কন্টেইনার প্রদান করে। NavHost একটি NavController, startDestination এবং Kotlin DSL এর মাধ্যমে নির্মিত একটি রুট গ্রাফ গ্রহণ করে। যখন বর্তমান রুট পরিবর্তিত হয়, NavHost নির্দিষ্ট অ্যানিমেশন সহ প্রদর্শিত composable সুইচ করে।
NavHost একটি স্ক্রিন সুইচার হিসেবে কাজ করে: এটি NavController থেকে বর্তমান NavBackStackEntry ট্র্যাক করে এবং সংশ্লিষ্ট composable ব্লক রেন্ডার করে। প্রতিটি স্ক্রিন একটি স্বাধীন composable ফাংশন যা রুট আর্গুমেন্ট সহ NavBackStackEntry গ্রহণ করে। সমস্ত স্ক্রিন একটি একক কম্পোজিশন ট্রিতে বিদ্যমান, কিন্তু NavHost একবারে শুধুমাত্র একটি দেখায়, বাকিগুলো অ্যানিমেশনের মাধ্যমে আড়াল করে।
FragmentManager এর বিপরীতে, NavHost প্রতিটি স্ক্রিনের জন্য একটি Fragment তৈরি করে না। সম্পূর্ণ জীবনচক্র CompositionLifecycle এর মাধ্যমে পরিচালিত হয় — composable ফাংশনে onStart/onResume থাকে না, তাই সাইড ইফেক্টের জন্য LaunchedEffect এবং DisposableEffect ব্যবহার করা হয়। NavHost স্বয়ংক্রিয়ভাবে NavController এ সাবস্ক্রাইব করে এবং রুট পরিবর্তন হলে UI পুনরায় কম্পোজ করে।
Google এর মতে, NavHost Navigation 2.4.0 থেকে একটি স্থিতিশীল API। 2.8.0 থেকে শুরু করে, NavHost Kotlin Serialization এর মাধ্যমে Type-Safe নেভিগেশন সমর্থন করে, স্ট্রিং রুটকে ডেটা ক্লাস দিয়ে প্রতিস্থাপন করে। NavHost নেস্টেড গ্রাফও সমর্থন করে, যা মডিউল-ভিত্তিক নেভিগেশন সংগঠন সক্ষম করে।
NavHost দুটি বাধ্যতামূলক প্যারামিটার দিয়ে তৈরি করা হয়: navController (NavHostController এর একটি ইনস্ট্যান্স) এবং startDestination (প্রথম স্ক্রিনের রুট স্ট্রিং)। তৃতীয় প্যারামিটার হল একটি বিল্ডার ব্লক যেখানে composable(), navigation() এবং dialog() এর মাধ্যমে সমস্ত রুট রেজিস্টার করা হয়।
@Composable
fun AppNavHost(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen(navController) }
composable("settings") { SettingsScreen(navController) }
}
}
startDestination হল সেই রুট যা NavHost প্রথমবার চালু হলে খোলে। যদি ব্যাক স্ট্যাক খালি থাকে, NavHost স্বয়ংক্রিয়ভাবে স্ট্যাকে startDestination যোগ করে। পুনর্বিন্যাস (স্ক্রিন রোটেশন) এ, NavHost savedState থেকে শেষ রুট পুনরুদ্ধার করে, startDestination নয়।
BottomNavigation এর জন্য, startDestination নিচের প্যানেলের একটি রুট। বাকি প্যানেল রুটগুলি পৃথক composable এন্ট্রি হিসেবে যোগ করা হয়। NavHost Scaffold.content এর ভিতরে স্থাপন করা উচিত — যেখানে প্রধান অ্যাপ্লিকেশন বিষয়বস্তু প্রদর্শিত হয়। NavHost TopAppBar এবং BottomNavigation বাদে সমস্ত উপলব্ধ উচ্চতা নেয়।
composable(route, arguments, deepLinks, enterTransition, exitTransition, content) ফাংশনটি NavHost গ্রাফে একটি রুট রেজিস্টার করে। route প্যারামিটার হল একটি স্ট্রিং যা {paramName} আকারে ঐচ্ছিক প্লেসহোল্ডার সহ পথ বর্ণনা করে। নেভিগেশনের সময় প্লেসহোল্ডারটি একটি প্রকৃত মান দ্বারা প্রতিস্থাপিত হয়।
composable এর content ব্লক একটি NavBackStackEntry গ্রহণ করে যা থেকে আর্গুমেন্ট বের করা হয়। স্ক্রিন composable ফাংশনটি কেবল তখনই রেন্ডার হয় যখন বর্তমান NavController রুট রুটের সাথে মেলে। অমিল হলে, composable কম্পোজিশন থেকে সরানো হয়, কিন্তু এর অবস্থা rememberSaveable বা SavedStateHandle সহ ViewModel এর মাধ্যমে সংরক্ষণ করা যেতে পারে।
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)
}
NavHost এর ভিতরে composable এন্ট্রির সংখ্যা কয়েক থেকে শত শত পর্যন্ত হতে পারে। বড় অ্যাপ্লিকেশনের জন্য, রুটগুলি মডিউলে বিভক্ত হয় এবং নেস্টেড গ্রাফের মাধ্যমে সংযুক্ত হয়। প্রতিটি composable এর নিজস্ব অ্যানিমেশন সেটিংস, ডিপ লিঙ্ক এবং আর্গুমেন্ট থাকতে পারে।
রুট আর্গুমেন্ট composable() এ arguments: List<NamedNavArgument> প্যারামিটারের মাধ্যমে সংজ্ঞায়িত করা হয়। প্রতিটি আর্গুমেন্ট navArgument(name) { type; defaultValue } এর মাধ্যমে সংজ্ঞায়িত করা হয়। NavType আর্গুমেন্টের ধরন নির্ধারণ করে: StringType, IntType, LongType, FloatType, BoolType, ParcelableType এবং ReferenceType।
| রুট প্যারামিটার | উদাহরণ রুট | NavType |
|---|---|---|
| পথ (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 নেভিগেশন সুপারিশ করা হয়: Kotlin Serialization সহ রুটের জন্য একটি sealed class বা data class সংজ্ঞায়িত করুন। স্ট্রিং রুটের পরিবর্তে, composable<RouteType> { backStackEntry -> } ব্যবহার করুন। এটি রুটে টাইপো দূর করে এবং আর্গুমেন্টের জন্য স্বয়ংক্রিয়ভাবে NavType জেনারেট করে। মাইগ্রেট করতে, navigation-compose-typesafe নির্ভরতা এবং Kotlin Serialization প্লাগইন যোগ করুন।
nested graphs — navigation(route, startDestination) ফাংশন ব্যবহার করে NavHost এর ভিতরে রুট গ্রুপ করার একটি প্রক্রিয়া। একটি নেস্টেড গ্রাফের নিজস্ব রুট উপসর্গ এবং startDestination থাকে এবং এর সমস্ত রুট উপসর্গের মাধ্যমে অ্যাক্সেসযোগ্য। নেস্টেড গ্রাফ মডিউলার আর্কিটেকচারের জন্য ব্যবহৃত হয়, যেখানে প্রতিটি ফিচার মডিউল তার নিজস্ব উপ-গ্রাফ রেজিস্টার করে।
নেস্টেড গ্রাফের সুবিধা: মডিউলের মধ্যে রুট বিচ্ছিন্নতা, স্ক্রিনের একটি গ্রুপের জন্য একীভূত ব্যাক স্ট্যাক এবং অভ্যন্তরীণ কাঠামো প্রকাশ না করে উপসর্গ দ্বারা নেভিগেট করার ক্ষমতা। উদাহরণস্বরূপ, "auth" গ্রাফে "auth/login" এবং "auth/register" রয়েছে। নেভিগেশন সম্পূর্ণ রুট দ্বারা অথবা 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) }
}
}
নেস্টেড গ্রাফ গ্রাফ স্তরে আর্গুমেন্ট পাসিং সমর্থন করে: গ্রাফের রুটে ঘোষিত প্যারামিটারগুলি সমস্ত অভ্যন্তরীণ রুটে পাস হয়। একটি নেস্টেড গ্রাফ সাফ করতে, popBackStack(route) ব্যবহার করুন — এটি সমস্ত অভ্যন্তরীণ এন্ট্রি সরিয়ে ফেলবে। নেস্টেড গ্রাফের কোনো গভীরতা সীমা নেই, কিন্তু পঠনযোগ্যতার জন্য 3 স্তরের বেশি সুপারিশ করা হয় না।
NavHost enterTransition, exitTransition, popEnterTransition এবং popExitTransition প্যারামিটারের মাধ্যমে composable রুটের মধ্যে ট্রানজিশন অ্যানিমেশন সমর্থন করে। অ্যানিমেশনগুলি একবার NavHost এর জন্য সেট করা হয় এবং সমস্ত রুটে প্রয়োগ করা হয়, অথবা প্রতিটি composable এর জন্য পৃথকভাবে। ডিফল্টরূপে, অ্যানিমেশনগুলি অক্ষম থাকে।
সাধারণ কনফিগারেশন: enterTransition = slideInHorizontally(initialOffsetX = { it }) — স্ক্রিন ডান দিক থেকে স্লাইড করে আসে; exitTransition = slideOutHorizontally(targetOffsetX = { -it }) — স্ক্রিন বাম দিকে স্লাইড করে যায়। পপ অ্যানিমেশনের জন্য, দিকগুলি উল্টে যায়: স্ক্রিন বাম দিক থেকে স্লাইড করে আসে এবং ডান দিকে স্লাইড করে যায়। BottomNavigation এর জন্য, স্লাইড ছাড়া fadeIn/fadeOut ব্যবহার করা হয়।
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 কন্টেইনার মাত্রা, অ্যানিমেশন অগ্রগতি এবং দিকে অ্যাক্সেস প্রদান করে। শেয়ার্ড এলিমেন্ট ট্রানজিশনের জন্য (একটি উপাদান মসৃণভাবে অন্য স্ক্রিনে চলে যায়), Accompanist Navigation Animation লাইব্রেরি বা sharedElement Modifier এর মাধ্যমে কাস্টম বাস্তবায়ন প্রয়োজন। Android Developers (2025) অনুযায়ী, ডিফল্ট স্লাইড অ্যানিমেশন (ডান দিক থেকে প্রবেশ, বাম দিকে প্রস্থান) নেভিগেশন সহ 80% Android অ্যাপ্লিকেশনে ব্যবহৃত হয়।
সচরাচর জিজ্ঞাস্য
প্রযুক্তিগতভাবে হ্যাঁ, কিন্তু সুপারিশ করা হয় না। প্রতিটি NavHost একটি স্বাধীন ব্যাক স্ট্যাক তৈরি করে, যা একীভূত নেভিগেশন ভেঙে দেয়। ব্যতিক্রম হল পৃথক এলাকা, যেমন মূল বিষয়বস্তুর জন্য NavHost এবং নিজস্ব নেভিগেশন সহ BottomSheet এর জন্য NavHost।
NavHost একটি নেভিগেশন কন্টেইনার যা স্ক্রিন সুইচ করে। Scaffold হল পুরো পৃষ্ঠার লেআউট (TopAppBar, BottomNavigation, FloatingActionButton)। সাধারণত, NavHost Scaffold.content এর ভিতরে স্থাপন করা হয়। Scaffold নেভিগেশন পরিচালনা করে না, এটি শুধুমাত্র UI উপাদানের জন্য স্লট প্রদান করে।
ViewModel NavBackStackEntry এর মধ্যে viewModel() এর মাধ্যমে তৈরি করা হয়। স্ক্রিনের মধ্যে ViewModel শেয়ার করতে, parentNavController ব্যবহার করুন: শেয়ার্ড ViewModel প্যারেন্ট এন্ট্রিতে বাঁধুন। বিকল্প হল NavGraph স্কোপ সহ DI (Hilt/Koin)।
এটি স্বাভাবিক আচরণ — রুট ছেড়ে যাওয়ার সময় NavHost composable কে কম্পোজিশন থেকে সরিয়ে দেয়। অবস্থা সংরক্ষণের জন্য, UI অবস্থার জন্য rememberSaveable এবং ব্যবসায়িক যুক্তির জন্য SavedStateHandle সহ ViewModel ব্যবহার করুন।
একটি শেষ রুট composable("404") যোগ করুন এবং অজানা ডিপ লিঙ্ক প্রাপ্ত হলে সেখানে নেভিগেট করুন। NavHost এর কোনো catch-all রুট নেই — navigate() এর আগে ডিপ লিঙ্ক ইন্টেন্ট হ্যান্ডলারে রুট পরীক্ষা করুন। যদি রুট খুঁজে না পাওয়া যায়, 404 এ নেভিগেট করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন