Navigation 3, Jetpack Compose के नेविगेशन स्टेट को हैंडल करने के तरीके में बुनियादी बदलाव को दिखाता है. साथ ही, यह Navigation 2 की तुलना में आर्किटेक्चर से जुड़े कई फ़ायदे देता है.
Wear Compose ऐप्लिकेशन को Navigation 2 से Navigation 3 पर माइग्रेट करने के लिए, आर्किटेक्चर में हुए बदलावों और ज़रूरी चरणों के बारे में जानें.
Navigation 3 के मुख्य फ़ायदे
- बैक स्टैक को सीधे तौर पर कंट्रोल करना:
NavBackStack, मूल रूप सेNavKeyऑब्जेक्ट की एक ऐसी सूची है जिसमें बदलाव किया जा सकता है. यह सूची, उपयोगकर्ता की विज़िट की गई स्क्रीन के इतिहास को दिखाती है. इसे ठीक उसी तरह कंट्रोल किया जाता है जैसे किसी KotlinMutableList(add,removeLast,clear) को कंट्रोल किया जाता है. नेविगेशन से जुड़ी कार्रवाइयाँ करने के लिए, सूची में सीधे बदलाव किया जाता है. जैसे, आगे बढ़ने के लिए कोई कुंजी जोड़ना या पीछे जाने के लिए कोई कुंजी हटाना. - Compose-First डिज़ाइन: बैक स्टैक को स्टैंडर्ड ऑब्ज़र्वेबल स्टेट के तौर पर मॉडल किया जाता है. नेविगेशन के इतिहास में बदलाव करने पर, कंपोज़ के किसी अन्य स्टेट को अपडेट करने जैसा ही व्यवहार होता है. इससे मौजूदा स्क्रीन दिखाने के लिए, अपने-आप रीकंपोज़िशन ट्रिगर हो जाता है.
- डिफ़ॉल्ट रूप से टाइप-सेफ़: स्ट्रिंग पर आधारित रास्तों को पूरी तरह से हटा दिया गया है. नेविगेशन में, क्रम से लगाए जा सकने वाले डेटा ऑब्जेक्ट और डेटा क्लास का इस्तेमाल किया जाता है.
- डिकपल्ड प्रज़ेंटेशन (सीन की रणनीतियां): यूज़र इंटरफ़ेस (यूआई) ट्रांज़िशन लेयर (
NavDisplayऔरSwipeDismissableSceneStrategy) को पूरी तरह से स्टेट ट्रैकिंग (NavBackStack) से अलग कर दिया गया है. इससे Wear OS में पहले से मौजूद नेविगेशन ट्रांज़िशन को आसानी से इंटिग्रेट किया जा सकता है.
माइग्रेशन के चरण
1. डिपेंडेंसी अपडेट करें
पुरानी androidx.wear.compose:compose-navigation डिपेंडेंसी हटा दी गई है. साथ ही, स्प्लिट नेविगेशन 3 की नई डिपेंडेंसी और Kotlin सीरियलाइज़ेशन सपोर्ट जोड़ा गया है.
हटाएं:
implementation("androidx.wear.compose:compose-navigation:...")
जोड़ें:
implementation("androidx.navigation3:navigation3-runtime:...") // State logic
implementation("androidx.navigation3:navigation3-ui:...") // Display logic
implementation("androidx.wear.compose:compose-navigation3:...") // Wear gestures
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:...") // Requires compiler plugin
2. NavKey को लागू करने के लिए डेस्टिनेशन अपडेट करना
Navigation 2 में, आपने रूटिंग के लिए स्ट्रिंग या सामान्य ऑब्जेक्ट का इस्तेमाल किया होगा. Navigation 3 में, आपको NavKey मार्कर इंटरफ़ेस लागू करना ज़रूरी है. साथ ही, हर स्क्रीन ऑब्जेक्ट को @Serializable से एनोटेट करना होगा.
यह क्यों आवश्यक है? बैक स्टैक को सेव किया जा सकता है और प्रोसेस बंद होने पर उसे वापस लाया जा सकता है. इसके लिए, navigation3-runtime, स्थिति को क्रम से लगाने के लिए kotlinx-serialization पर निर्भर करता है.
पहले (Navigation 2 - Generic Type-Safe Routes):
sealed class Nav2Screen { data object Landing : Nav2Screen() data object List : Nav2Screen() }
इसके बाद (Navigation 3 - NavKey + Serializable):
@Serializable sealed interface MigrationScreen : NavKey { @Serializable data object Landing : MigrationScreen @Serializable data object List : MigrationScreen }
3. रूटिंग लॉजिक (NavController से NavBackStack) को बदलें
NavController को NavBackStack से बदलें. इसे rememberNavBackStack का इस्तेमाल करके शुरू किया गया है. आपको Wear OS के लिए, SwipeDismissableSceneStrategy को भी इंस्टैंशिएट करना होगा.
पहले (नेविगेशन 2):
val navController = rememberSwipeDismissableNavController()
इसके बाद (नेविगेशन 3):
val backStack = rememberNavBackStack(MigrationScreen.Landing as NavKey) val strategy = rememberSwipeDismissableSceneStrategy<NavKey>()
4. NavHost को NavDisplay और entryProvider डीएसएल से बदलें
NavHost कंटेनर और इसके इंटरनल composable("route") { ... } बिल्डर डीएसएल को NavDisplay और entryProvider {
entry<Key> { ... } } डीएसएल से बदल दिया गया है.
पहले (नेविगेशन 2):
SwipeDismissableNavHost(navController = navController, startDestination = "menu") { composable("menu") { GreetingScreen( onShowList = { navController.navigate("list") } ) } composable("list") { ListScreen() } }
इसके बाद (नेविगेशन 3):
NavDisplay( backStack = backStack, sceneStrategies = listOf(strategy), entryProvider = entryProvider { entry<MigrationScreen.Landing> { GreetingScreen( onShowList = { backStack.add(MigrationScreen.List) } ) } entry<MigrationScreen.List> { ListScreen() } } )