Navigation Compose হল Jetpack Compose-এ নির্মিত Android অ্যাপ্লিকেশনের ভেতরে ডিক্লেয়ারেটিভ নেভিগেশনের জন্য একটি Jetpack লাইব্রেরি। FragmentManager বা Intent-ভিত্তিক নেভিগেশনের পরিবর্তে, Navigation Compose একটি একীভূত রুট গ্রাফ অফার করে যা NavController এবং NavHost-এর মাধ্যমে পরিচালিত হয়। Google I/O (2025) অনুসারে, Navigation Compose হল Compose অ্যাপ্লিকেশনের জন্য প্রস্তাবিত নেভিগেশন পদ্ধতি, যা 70% এরও বেশি নতুন প্রকল্পে ব্যবহৃত হয়। লাইব্রেরিটি টাইপকৃত আর্গুমেন্ট পাস করা, ডিপ লিংক, ট্রানজিশন অ্যানিমেশন এবং SavedStateHandle-এর মাধ্যমে ViewModel-এর সাথে একীকরণ সমর্থন করে।
মূল বিষয়
Navigation Compose হল Jetpack স্যুটের একটি লাইব্রেরি যা Compose অ্যাপ্লিকেশনের জন্য নেভিগেশন ফ্রেমওয়ার্ক প্রদান করে। লাইব্রেরিটি View সিস্টেমের জন্য নেভিগেশন কম্পোনেন্টের মতো একই নীতির উপর ভিত্তি করে তৈরি, তবে Compose-এর ডিক্লেয়ারেটিভ প্রকৃতির সাথে খাপ খাইয়ে নেওয়া হয়েছে: FragmentTransaction-এর পরিবর্তে composable ফাংশন ব্যবহার করা হয়, এবং নেভিগেশন গ্রাফ Kotlin DSL-এর মাধ্যমে নির্মিত হয়।
Navigation Compose এবং ক্লাসিক নেভিগেশনের মধ্যে মূল পার্থক্য হল FragmentManager-এর অনুপস্থিতি। প্রতিটি স্ক্রিন একটি composable ফাংশন যা রুট ম্যাচ করলে NavHost-এ রেন্ডার হয়। ব্যাক স্ট্যাক Fragment নয়, বরং রুট, আর্গুমেন্ট এবং অবস্থা সহ একটি রেকর্ড সংরক্ষণ করে। এটি আর্কিটেকচারকে সরল করে এবং Fragment-ভিত্তিক নেভিগেশনের জন্য সাধারণ লাইফসাইকেল দ্বন্দ্ব দূর করে।
Google (2025) অনুসারে, Navigation Compose পরীক্ষামূলক থেকে স্থিতিশীল হয়েছে এবং সংস্করণ 2.8.0 থেকে Jetpack-এর অংশ। লাইব্রেরিটি Material3, Type-Safe Navigation (Kotlin Serialization-এর মাধ্যমে), নেস্টেড গ্রাফ এবং মডিউলারাইজেশন সমর্থন করে। একমাত্র সীমাবদ্ধতা হল লাইব্রেরিটি ম্যানুয়াল কনফিগারেশন ছাড়া BottomNavigation-এর জন্য মাল্টি-ব্যাক স্ট্যাক সমর্থন করে না, যদিও Google এটিতে কাজ করছে।
Navigation Compose-এর আর্কিটেকচার তিনটি সত্তাকে কেন্দ্র করে: NavController (স্ট্যাক ব্যবস্থাপনা), NavHost (গ্রাফ কন্টেইনার) এবং NavDestination (composable সহ পৃথক রুট)। তাদের মধ্যে মিথস্ক্রিয়া ডিক্লেয়ারেটিভ: ডেভেলপার রুট এবং আর্গুমেন্ট বর্ণনা করে, এবং লাইব্রেরি লোডিং, সংরক্ষণ এবং পুনরুদ্ধার অবস্থাগুলি পরিচালনা করে।
NavController হল Navigation Compose-এর কেন্দ্রীয় উপাদান, যা নেভিগেশন স্ট্যাক পরিচালনা করে। এটি rememberNavController()-এর মাধ্যমে তৈরি করা হয় এবং NavHost-এ পাস করা হয়। NavController ব্যাক স্ট্যাক, বর্তমান এন্ট্রি পয়েন্ট সংরক্ষণ করে এবং বিলম্বিত কর্ম (গ্রাফ ইনিশিয়ালাইজেশনের পরে ডিপলিংক) সমর্থন করে।
@Composable
fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("profile/{userId}") { backStackEntry ->
ProfileScreen(
userId = backStackEntry.arguments?.getString("userId") ?: ""
)
}
}
}
NavController-এর প্রধান পদ্ধতি: navigate(route) — একটি রুটে নেভিগেট করুন, popBackStack() — পূর্ববর্তী স্ক্রিনে ফিরে যান, navigateAndClear(route) — স্ট্যাক সাফ করে নেভিগেট করুন। NavOptions আচরণ নির্দিষ্ট করে: launchSingleTop ডুপ্লিকেট প্রতিরোধ করে, popUpTo নির্দিষ্ট রুট পর্যন্ত স্ট্যাক সাফ করে, restoreState পূর্ববর্তী অবস্থা পুনরুদ্ধার করে।
গভীরভাবে নেস্টেড composable ফাংশন থেকে NavController অ্যাক্সেস করতে, CompositionLocal-এর মাধ্যমে NavHostController ব্যবহার করুন। LocalNavController NavHost-এর ভিতরে ScopedNavController-এ প্রদান করা হয়। NavHost-এর বাইরে (যেমন, BottomNavigation-এ), কন্ট্রোলার প্যারামিটার বা ViewModel-এর মাধ্যমে পাস করা হয়।
NavHost হল একটি composable কন্টেইনার যা NavController-কে রুট গ্রাফের সাথে সংযুক্ত করে। প্রতিটি রুট composable(route, arguments, deepLinks)-এর মাধ্যমে ঘোষিত হয়, যেখানে route হল ঐচ্ছিক {param} প্লেসহোল্ডার সহ একটি রুট স্ট্রিং। বর্তমান রুট ম্যাচ করলে, NavHost সংশ্লিষ্ট composable ব্লক রেন্ডার করে।
রুট গ্রাফ শ্রেণিবদ্ধভাবে নির্মিত: একটি মডিউলের মধ্যে রুট গ্রুপ করতে navigation()-এর মাধ্যমে গ্রাফ নেস্ট করা যেতে পারে। নেস্টেড গ্রাফের নিজস্ব 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) }
}
}
NavHost স্বয়ংক্রিয়ভাবে LocalBackDispatcher-এর মাধ্যমে সিস্টেম ব্যাক বাটন (ব্যাক প্রেস) পরিচালনা করে। Material3 Scaffold-এ, এটি ডিফল্টভাবে সঠিক BottomNavigation অপারেশনের জন্য NavController গ্রহণ করে। NavHost রুট পরিবর্তন হলে composable পুনরায় তৈরি করে, কিন্তু ইনপুট ফিল্ড এবং স্ক্রলের জন্য rememberSaveable-এর মাধ্যমে অবস্থা সংরক্ষণ করে।
Navigation Compose রুট প্যারামিটার এবং NavType-এর মাধ্যমে স্ক্রিনের মধ্যে টাইপকৃত আর্গুমেন্ট পাস করা সমর্থন করে। প্যারামিটারগুলি রুটে {paramName} হিসাবে নির্দিষ্ট করা হয় এবং composable()-এ arguments-এর মাধ্যমে প্রকার নির্দেশিত হয়। NavType String, Int, Long, Float, Boolean, Parcelable এবং Serializable সমর্থন করে।
| আর্গুমেন্টের ধরন | NavType | রুট উদাহরণ |
|---|---|---|
| String | NavType.StringType | "profile/{name}" |
| Int | NavType.IntType | "item/{id}" |
| Boolean | NavType.BoolType | "settings?enabled={flag}" |
| Parcelable | NavType.ParcelableType | "details/{item}" |
| Float | NavType.FloatType | "map?lat={lat}&lng={lng}" |
আর্গুমেন্টগুলি NavBackStackEntry থেকে arguments?.getType(key)-এর মাধ্যমে নিষ্কাশিত হয়। বাধ্যতামূলক প্যারামিটারের জন্য defaultValue ব্যবহার করুন, ঐচ্ছিকের জন্য — nullable। Parcelable সমর্থন শুধুমাত্র Kotlin Parcelize বা kotlinx.parcelize লাইব্রেরির সাথে কাজ করে। জটিল অবজেক্টের জন্য, সম্পূর্ণ অবজেক্ট সিরিয়ালাইজ করার পরিবর্তে ID পাস করা এবং ViewModel-এর মাধ্যমে ডেটা লোড করার পরামর্শ দেওয়া হয়।
Navigation 2.8.0 থেকে, Kotlin Serialization-এর সাথে Type-Safe Navigation চালু হয়েছে: রুটগুলি ডেটা ক্লাস হিসাবে এবং আর্গুমেন্টগুলি ফিল্ড হিসাবে সংজ্ঞায়িত করা হয়। এটি স্ট্রিং রুটকে টাইপকৃত অবজেক্টে প্রতিস্থাপন করে এবং রুট নামের ত্রুটিগুলি দূর করে। মাইগ্রেশনের জন্য Kotlin Serialization প্লাগইন এবং navigation-compose-typesafe নির্ভরতা প্রয়োজন।
@Serializable
/* sealed class Route */
sealed class ProfileRoute(val route: String) {
data object Home : ProfileRoute("home")
data class Profile(val userId: String) : ProfileRoute("profile/{userId}")
}
ডিপ লিংক হল একটি নেভিগেশন প্রক্রিয়া যা URL বা intent-filter-এর মাধ্যমে একটি নির্দিষ্ট অ্যাপ্লিকেশন স্ক্রিন খোলার অনুমতি দেয়। Navigation Compose-এ, ডিপ লিংকগুলি composable()-এ deepLinks প্যারামিটারের মাধ্যমে কনফিগার করা হয় এবং URI প্যাটার্নের সাথে ম্যাচ করলে স্বয়ংক্রিয়ভাবে প্রক্রিয়াকৃত হয়।
একটি ডিপ লিংক UriPattern তালিকা হিসাবে নির্দিষ্ট করা হয়: "https://example.com/profile/{userId}". URI প্যারামিটারগুলি স্বয়ংক্রিয়ভাবে রুট আর্গুমেন্টে ম্যাপ হয়। NavController অ্যাপ্লিকেশন স্টার্টআপে (intent-এর মাধ্যমে) এবং অপারেশন চলাকালীন (অন্তর্নিহিত ডিপ লিংকের মাধ্যমে) ডিপ লিংক প্রক্রিয়া করে। মুলতুবি ডিপ লিংকগুলি পরিচালনা করতে, গ্রাফ ইনিশিয়ালাইজেশনের পরে NavController-এ handleDeepLink() ব্যবহার করুন।
Google-এর মতে, ডিপ লিংকগুলি সুপারিশ করা হয়: পুশ (Firebase Dynamic Links), ইমেল যাচাইকরণ, কন্টেন্ট শেয়ারিং এবং ওয়েব লিংক থেকে ক্রস-নেভিগেশনের জন্য। Android 12+-এর জন্য, ডিপ লিংক কর্তৃত্ব যাচাই করতে Digital Asset Links ব্যবহার করা হয়। AndroidManifest.xml-এ ডায়ালগ ছাড়া লিংক খোলার জন্য autoVerify="true" সহ intent-filter থাকতে হবে।
composable(
route = "profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType }),
deepLinks = listOf(
navDeepLink { uriPattern = "https://example.com/profile/{userId}" }
)
) { backStackEntry ->
ProfileScreen(userId = backStackEntry.arguments?.getString("userId") ?: "")
}
Navigation Compose-এ ডিপ লিংকের সীমাবদ্ধতা: লাইব্রেরিটি বিলম্বিত ডিপ লিংক সমর্থন করে না — একটি ডিপ লিংক শুধুমাত্র NavHost সম্পূর্ণরূপে গ্রাফ তৈরি করার পরেই প্রক্রিয়াকৃত হয়। যদি গ্রাফ ইনিশিয়ালাইজেশনের আগে ডিপ লিংক আসে, তবে এটি intent?.data-এর মাধ্যমে বিলম্বিত করতে হবে এবং LaunchedEffect-এ প্রক্রিয়া করতে হবে। Firebase Dynamic Links-এর জন্য, Navigation Compose-এর সাথে Firebase Dynamic Links SDK ব্যবহার করুন।
Navigation Compose composable()-এ enterTransition, exitTransition, popEnterTransition এবং popExitTransition প্যারামিটারের মাধ্যমে ট্রানজিশন অ্যানিমেশন সমর্থন করে। অ্যানিমেশনগুলি Compose Animation API ব্যবহার করে বাস্তবায়িত হয়: fadeIn, slideInHorizontally, expandIn এবং অন্যান্য। ডিফল্টভাবে, অ্যানিমেশন নিষ্ক্রিয় — স্ক্রিনগুলি তাৎক্ষণিকভাবে প্রতিস্থাপিত হয়।
সাধারণ অ্যানিমেশন পরিস্থিতি: সামনের নেভিগেশনের জন্য slideInHorizontally (স্ক্রিন ডান দিক থেকে আসে), ফিরে আসার জন্য slideOutHorizontally (স্ক্রিন ডান দিকে যায়)। BottomNavigation-এর জন্য, স্লাইড ছাড়া ফেইড অ্যানিমেশন বেশি সাধারণভাবে ব্যবহৃত হয়। অ্যানিমেশনগুলি NavHost-এর মাধ্যমে সেট করা হয় এবং সমস্ত composable-এ প্রযোজ্য হয় যদি না পৃথক অ্যানিমেশন নির্দিষ্ট করা হয়।
NavHost(
navController = navController,
startDestination = "home",
enterTransition = { slideInHorizontally() + fadeIn() },
exitTransition = { slideOutHorizontally() + fadeOut() },
popEnterTransition = { fadeIn() },
popExitTransition = { slideOutHorizontally() + fadeOut() }
) { /* composable */ }
অ্যানিমেশন প্যারামিটার সরাসরি composable()-এ পাস করে প্রতিটি composable-এর জন্য পৃথকভাবে অ্যানিমেশন ওভাররাইড করা যেতে পারে। গুরুত্বপূর্ণ বিষয় হল, অ্যানিমেশনগুলি সিস্টেম ব্যাক প্রেস অ্যানিমেশনের সাথে বিরোধ করা উচিত নয়। শেয়ার্ড এলিমেন্ট ট্রানজিশনের জন্য, accompanist-navigation-animation লাইব্রেরি বা Modifier.graphicsLayer-এর মাধ্যমে কাস্টম বাস্তবায়ন প্রয়োজন। Android Developers (2025) অনুসারে, 80% প্রোডাকশন অ্যাপ্লিকেশন স্ট্যান্ডার্ড নেভিগেশনের জন্য স্লাইড অনুভূমিক অ্যানিমেশন ব্যবহার করে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Navigation Compose Fragment ছাড়া কাজ করে, গ্রাফের জন্য composable ফাংশন এবং Kotlin DSL ব্যবহার করে। নেভিগেশন কম্পোনেন্ট (View) FragmentManager এবং XML গ্রাফের উপর ভিত্তি করে তৈরি। Compose সংস্করণটি সরল, দ্রুত এবং এর Fragment লাইফসাইকেল নেই। View-এর জন্য নেভিগেশন কম্পোনেন্ট শুধুমাত্র হাইব্রিড অ্যাপ্লিকেশনের জন্য উপযুক্ত।
অবজেক্ট ID পাস করার এবং SavedStateHandle সহ ViewModel-এর মাধ্যমে ডেটা লোড করার পরামর্শ দেওয়া হয়। যদি অবজেক্টটি সরল হয়, তাহলে kotlinx.parcelize-এর মাধ্যমে Parcelable ব্যবহার করুন। সরাসরি আর্গুমেন্ট (Bundle)-এর মাধ্যমে বড় অবজেক্ট পাস করা ~1 MB-তে সীমাবদ্ধ এবং TransactionTooLargeException ঘটাতে পারে।
হ্যাঁ, NavHost-এর ভিতরে navigation(route, startDestination) ফাংশনের মাধ্যমে। নেস্টেড গ্রাফের নিজস্ব startDestination থাকে এবং একটি সাধারণ রুট উপসর্গের অধীনে একত্রিত হয়। এটি প্রতিটি ফিচার মডিউলের জন্য বিচ্ছিন্ন গ্রাফ সহ একটি মডিউলার আর্কিটেকচার সংগঠিত করার অনুমতি দেয়।
NavController স্বয়ংক্রিয়ভাবে Compose-এর BackHandler-এর মাধ্যমে ব্যাক প্রেস পরিচালনা করে। ব্যাক চাপলে navController.popBackStack() কল করুন। কাস্টম হ্যান্ডলিং (প্রস্থান নিশ্চিতকরণ)-এর জন্য, popBackStack() কল করার আগে BackHandler(enabled = condition) { callback } ব্যবহার করুন।
বর্তমানে, Navigation Compose Compose Multiplatform-এ সমর্থিত নয়। ক্রস-প্ল্যাটফর্ম প্রকল্পের iOS অংশের জন্য, Voyager বা Decompose ব্যবহার করুন। Google KMP সমর্থনে কাজ করছে, কিন্তু কোনো রিলিজ সময়সীমা নেই। শুধুমাত্র Android প্রকল্পের জন্য, Navigation Compose একমাত্র প্রস্তাবিত বিকল্প।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন