गाइड: Compose और Navigation 2 में टाइप-सेफ़ नेविगेशन पर माइग्रेट करना

इस गाइड में, स्ट्रिंग पर आधारित रास्तों को क्रम से लगाने लायक Kotlin टाइप से बदलने की प्रोसेस के बारे में बताया गया है. इससे कंपाइल-टाइम की सुरक्षा मिलती है. साथ ही, टाइपिंग की गड़बड़ियों या गलत आर्ग्युमेंट टाइप की वजह से होने वाली रनटाइम क्रैश की समस्या को ठीक किया जा सकता है.

ज़रूरी शर्तें

माइग्रेशन शुरू करने से पहले, पुष्टि करें कि आपका प्रोजेक्ट इन ज़रूरी शर्तों को पूरा करता हो:

  1. नेविगेशन वर्शन: Jetpack Navigation 2.8.0 या इसके बाद के वर्शन पर अपडेट करें
  2. Kotlin serialization plugin:
  3. libs.versions.toml में प्लगिन जोड़ें:
[libraries]
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }

[plugins]
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
  • डिपेंडेंसी को अपने टॉप-लेवल build.gradle.kts और मॉड्यूल-लेवल build.gradle.kts में जोड़ें.

पहला चरण: अपने डेस्टिनेशन तय करना

अपनी कॉन्स्टेंट रूट स्ट्रिंग को @Serializable ऑब्जेक्ट और क्लास से बदलें.

  • आर्ग्युमेंट के बिना स्क्रीन के लिए: data object का इस्तेमाल करें
  • तर्क वाली स्क्रीन के लिए: data class का इस्तेमाल करें

पहले (स्ट्रिंग पर आधारित):

const val ROUTE_HOME = "home"
const val ROUTE_PROFILE = "profile/{userId}"

इसके बाद (टाइप सेफ़):

import kotlinx.serialization.Serializable

@Serializable
object Home

@Serializable
data class Profile(val userId: String)

दूसरा चरण: NavHost कॉन्फ़िगरेशन अपडेट करना

composable और dialog फ़ंक्शन में नए सामान्य टाइप का इस्तेमाल करने के लिए, NavHost को अपडेट करें.

इससे पहले:

NavHost(navController, startDestination = "home") {
    composable("home") { HomeScreen(...) }
    composable("profile/{userId}") { backStackEntry ->
        val userId = backStackEntry.arguments?.getString("userId")
        ProfileScreen(userId)
    }
}

इसके बाद:

NavHost(navController, startDestination = Home) {
    composable<Home> {
        HomeScreen(...)
    }
    composable<Profile> { backStackEntry ->
        // The library automatically handles argument extraction
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(profile.userId)
    }
}

तीसरा चरण: टाइप-सेफ़ नेविगेशन कॉल लागू करना

स्ट्रिंग-इंटरपोलेटेड नेविगेशन कॉल को क्लास इंस्टेंस से बदलें.

इससे पहले:

navController.navigate("profile/user123")

इसके बाद:

navController.navigate(Profile(userId = "user123"))

चौथा चरण: ViewModels में आर्ग्युमेंट ऐक्सेस करना

अगर ViewModel का इस्तेमाल किया जाता है, तो अब SavedStateHandle से सीधे तौर पर रूट ऑब्जेक्ट निकाला जा सकता है.

लागू करना:

class ProfileViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    // Automatically parses arguments into the Profile class
    private val profile = savedStateHandle.toRoute<Profile>()
    val userId = profile.userId
}

पांचवां चरण: (ऐडवांस) कस्टम टाइप मैनेज करना

अगर आपको जटिल डेटा क्लास (सिर्फ़ प्रिमिटिव नहीं) पास करनी हैं, तो आपको कस्टम NavType तय करना होगा.

  1. कस्टम टाइप बनाएं: ```kotlin val SearchFilterType = object : NavType(isNullableAllowed = false) { override fun get(bundle: Bundle, key: String): SearchFilter? = Json.decodeFromString(bundle.getString(key) ?: return null)
override fun parseValue(value: String): SearchFilter =
    Json.decodeFromString(Uri.decode(value))

override fun put(bundle: Bundle, key: String, value: SearchFilter) {
    bundle.putString(key, Json.encodeToString(value))
}

}



2. **Register it in the Graph**:
```kotlin
composable<Search>(
    typeMap = mapOf(typeOf<SearchFilter>() to SearchFilterType)
) { ... }

सबसे सही तरीके और सुझाव

  • सील्ड हैरारकी: बड़े ऐप्लिकेशन के लिए, नेविगेशन स्ट्रक्चर को व्यवस्थित रखने के लिए, सील्ड इंटरफ़ेस या क्लास का इस्तेमाल करके अपने रास्तों को ग्रुप करें
  • ऑब्जेक्ट इंस्टेंस: पैरामीटर के बिना रास्तों के लिए, गैर-ज़रूरी असाइनमेंट से बचने के लिए हमेशा class के बजाय object का इस्तेमाल करें
  • बिना किसी वैल्यू वाले टाइप: नया एपीआई, बिना किसी वैल्यू वाले टाइप (उदाहरण के लिए, data class Search(val query: String?)) के साथ काम करता है. साथ ही, डिफ़ॉल्ट वैल्यू अपने-आप उपलब्ध कराता है
  • जांच करना: यूज़र इंटरफ़ेस (यूआई) की जांच के दौरान, टाइप-सेफ़ तरीके से मौजूदा डेस्टिनेशन की जांच करने के लिए navController.currentBackStackEntry?.hasRoute<T>() का इस्तेमाल करें