किसी ऐप्लिकेशन में स्टेट, कोई भी ऐसी वैल्यू होती है जो समय के साथ बदल सकती है. यह एक बहुत ही सामान्य डेफ़िनिशन है. इसमें Room डेटाबेस से लेकर किसी क्लास में मौजूद वैरिएबल तक, सब कुछ शामिल है.
Android के सभी ऐप्लिकेशन, उपयोगकर्ता को स्टेट दिखाते हैं. Android ऐप्लिकेशन में स्टेट के कुछ उदाहरण:
- एक Snackbar, जो तब दिखता है, जब नेटवर्क कनेक्शन नहीं बनाया जा सकता.
- एक ब्लॉग पोस्ट और उससे जुड़ी टिप्पणियां.
- बटन पर रिपल ऐनिमेशन, जो तब चलते हैं, जब कोई उपयोगकर्ता उन पर क्लिक करता है.
- ऐसे स्टिकर जिन्हें उपयोगकर्ता किसी इमेज पर बना सकता है.
Jetpack Compose की मदद से, यह साफ़ तौर पर बताया जा सकता है कि Android ऐप्लिकेशन में स्टेट को कहां और कैसे स्टोर और इस्तेमाल किया जाता है. इस गाइड में, स्टेट और कंपोज़ेबल के बीच कनेक्शन पर फ़ोकस किया गया है. साथ ही, इसमें उन एपीआई के बारे में बताया गया है जो Jetpack Compose, स्टेट के साथ आसानी से काम करने के लिए उपलब्ध कराता है.
स्टेट और कंपोज़िशन
Compose, डिक्लेरेटिव है. इसलिए, इसे अपडेट करने का सिर्फ़ एक तरीका है. वह यह है कि नए आर्ग्युमेंट के साथ उसी कंपोज़ेबल को कॉल किया जाए. ये आर्ग्युमेंट, यूज़र इंटरफ़ेस (यूआई) स्टेट के उदाहरण हैं. जब भी कोई स्टेट अपडेट होती है, तो रीकंपोज़िशन होता है. नतीजतन, TextField जैसी चीज़ें, XML पर आधारित ज़रूरी व्यू की तरह अपने-आप अपडेट नहीं होतीं. किसी कंपोज़ेबल को अपडेट करने के लिए, उसे साफ़ तौर पर नई स्टेट के बारे में बताना होता है.
@Composable private fun HelloContent() { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Hello!", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) OutlinedTextField( value = "", onValueChange = { }, label = { Text("Name") } ) } }
अगर इसे चलाया जाए और टेक्स्ट डालने की कोशिश की जाए, तो आपको दिखेगा कि कुछ नहीं होता. ऐसा इसलिए होता है, क्योंकि TextField अपने-आप अपडेट नहीं होता. यह तब अपडेट होता है, जब इसका value पैरामीटर बदलता है. ऐसा Compose में कंपोज़िशन और रीकंपोज़िशन के काम करने के तरीके की वजह से होता है.
शुरुआती कंपोज़िशन और रीकंपोज़िशन के बारे में ज़्यादा जानने के लिए, Compose में सोचने का तरीका देखें.
कंपोज़ेबल में स्टेट
कंपोज़ेबल फ़ंक्शन, मेमोरी में किसी ऑब्जेक्ट को स्टोर करने के लिए,
remember
एपीआई का इस्तेमाल कर सकते हैं. remember से कैलकुलेट की गई वैल्यू, शुरुआती कंपोज़िशन के दौरान कंपोज़िशन में स्टोर की जाती है. साथ ही, रीकंपोज़िशन के दौरान स्टोर की गई वैल्यू वापस की जाती है.
remember का इस्तेमाल, बदले जा सकने वाले और नहीं बदले जा सकने वाले, दोनों तरह के ऑब्जेक्ट को स्टोर करने के लिए किया जा सकता है.
rememberremember
mutableStateOf
एक ऑब्ज़र्वेबल
MutableState<T> बनाता है,
यह कंपोज़ रनटाइम के साथ इंटिग्रेट किया गया एक ऑब्ज़र्वेबल टाइप है.
interface MutableState<T> : State<T> {
override var value: T
}
value में किसी भी तरह का बदलाव होने पर, उन सभी कंपोज़ेबल फ़ंक्शन का रीकंपोज़िशन शेड्यूल हो जाता है जो value को पढ़ते हैं.
किसी कंपोज़ेबल में MutableState ऑब्जेक्ट को तीन तरीकों से एलान किया जा सकता है:
val mutableState = remember { mutableStateOf(default) }var value by remember { mutableStateOf(default) }val (value, setValue) = remember { mutableStateOf(default) }
ये एलान एक जैसे हैं. इन्हें स्टेट के अलग-अलग इस्तेमाल के लिए, सिंटैक्स शुगर के तौर पर उपलब्ध कराया गया है. आपको वह एलान चुनना चाहिए जिससे लिखा जा रहा कंपोज़ेबल, आसानी से पढ़ा जा सके.
by डेलिगेट सिंटैक्स के लिए, इन इंपोर्ट की ज़रूरत होती है:
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
याद रखी गई वैल्यू का इस्तेमाल, अन्य कंपोज़ेबल के लिए पैरामीटर के तौर पर या स्टेटमेंट में लॉजिक के तौर पर भी किया जा सकता है. इससे यह तय किया जा सकता है कि कौनसे कंपोज़ेबल दिखाए जाएं. उदाहरण के लिए, अगर नाम खाली होने पर, आपको बधाई मैसेज नहीं दिखाना है, तो if स्टेटमेंट में स्टेट का इस्तेमाल करें:
@Composable fun HelloContent() { Column(modifier = Modifier.padding(16.dp)) { var name by remember { mutableStateOf("") } if (name.isNotEmpty()) { Text( text = "Hello, $name!", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) } OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Name") } ) } }
remember की मदद से, रीकंपोज़िशन के दौरान स्टेट को बनाए रखा जा सकता है. हालांकि, कॉन्फ़िगरेशन में बदलाव होने पर स्टेट को बनाए नहीं रखा जा सकता. इसके लिए, आपको rememberSaveable का इस्तेमाल करना होगा. rememberSaveable , Bundle में सेव की जा सकने वाली किसी भी वैल्यू को अपने-आप सेव कर लेता है. अन्य वैल्यू के लिए, कस्टम सेवर ऑब्जेक्ट पास किया जा सकता है.
स्टेट के अन्य टाइप जिनका इस्तेमाल किया जा सकता है
Compose के लिए, स्टेट को होल्ड करने के लिए MutableState<T> का इस्तेमाल करना ज़रूरी नहीं है. यह
अन्य ऑब्ज़र्वेबल टाइप के साथ काम करता है. Compose में किसी अन्य ऑब्ज़र्वेबल टाइप को पढ़ने से पहले, उसे State<T> में बदलना ज़रूरी है, ताकि स्टेट में बदलाव होने पर कंपोज़ेबल अपने-आप रीकंपोज़ हो सकें.
Compose में, Android ऐप्लिकेशन में इस्तेमाल किए जाने वाले सामान्य ऑब्ज़र्वेबल
टाइप से State<T> बनाने के लिए फ़ंक्शन शामिल हैं. इन इंटिग्रेशन का इस्तेमाल करने से पहले, नीचे बताए गए तरीके से सही आर्टफ़ैक्ट जोड़ें:
Flow:collectAsStateWithLifecycle()collectAsStateWithLifecycle(), लाइफ़साइकल के बारे में जानकारी रखने वाले तरीके सेFlowसे वैल्यू इकट्ठा करता है. इससे, आपका ऐप्लिकेशन, ऐप्लिकेशन के संसाधनों को बचा पाता है. यह ComposeStateसे एमिट की गई सबसे नई वैल्यू दिखाता है. Android ऐप्लिकेशन पर फ़्लो इकट्ठा करने के लिए, इस एपीआई का इस्तेमाल करने का सुझाव दिया जाता है.डिपेंडेंसी
build.gradleफ़ाइल में ज़रूरी है. यह 2.6.0-beta01 या इससे नया वर्शन होना चाहिए:
Kotlin
dependencies {
...
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.10.0")
}
शानदार
dependencies {
...
implementation "androidx.lifecycle:lifecycle-runtime-compose:2.10.0"
}
-
collectAsStatecollectAsStateWithLifecycleजैसा ही है, क्योंकि यह भीFlowसे वैल्यू इकट्ठा करता है और उन्हें ComposeStateमें बदलता है.प्लेटफ़ॉर्म-अग्नोस्टिक कोड के लिए
collectAsStateका इस्तेमाल करें, न किcollectAsStateWithLifecycle, जो सिर्फ़ Android के लिए है.collectAsStateके लिए, अतिरिक्त डिपेंडेंसी की ज़रूरत नहीं होती, क्योंकि यहcompose-runtimeमें उपलब्ध है. -
observeAsState()इसLiveDataको ऑब्ज़र्व करना शुरू करता है और इसकी वैल्यू कोStateके ज़रिए दिखाता है.निम्न डिपेंडेंसी
build.gradleफ़ाइल में आवश्यक है:
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-livedata:1.11.0")
}
शानदार
dependencies {
...
implementation "androidx.compose.runtime:runtime-livedata:1.11.0"
}
-
subscribeAsState()एक्सटेंशन फ़ंक्शन हैं. ये RxJava2 की रिएक्टिव स्ट्रीम (जैसे,Single,Observable,Completable) को ComposeStateमें बदलते हैं.निम्न डिपेंडेंसी
build.gradleफ़ाइल में आवश्यक है:
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-rxjava2:1.11.0")
}
शानदार
dependencies {
...
implementation "androidx.compose.runtime:runtime-rxjava2:1.11.0"
}
-
subscribeAsState()एक्सटेंशन फ़ंक्शन हैं. ये RxJava3 की रिएक्टिव स्ट्रीम (जैसे,Single,Observable,Completable) को ComposeStateमें बदलते हैं.निम्न डिपेंडेंसी
build.gradleफ़ाइल में आवश्यक है:
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-rxjava3:1.11.0")
}
शानदार
dependencies {
...
implementation "androidx.compose.runtime:runtime-rxjava3:1.11.0"
}
स्टेटफ़ुल बनाम स्टेटलेस
कोई कंपोज़ेबल, किसी ऑब्जेक्ट को स्टोर करने के लिए remember का इस्तेमाल करता है, तो वह इंटरनल स्टेट बनाता है. इससे कंपोज़ेबल स्टेटफ़ुल बन जाता है. HelloContent , स्टेटफ़ुल कंपोज़ेबल का एक उदाहरण है, क्योंकि यह इंटरनल तौर पर अपनी name स्टेट को होल्ड और उसमें बदलाव करता है. यह उन स्थितियों में काम का हो सकता है जहां कॉलर को स्टेट को कंट्रोल करने की ज़रूरत नहीं होती और वह स्टेट को मैनेज किए बिना उसका इस्तेमाल कर सकता है. हालांकि, इंटरनल स्टेट वाले कंपोज़ेबल को फिर से इस्तेमाल करना मुश्किल होता है और उन्हें टेस्ट करना भी मुश्किल होता है.
स्टेटलेस कंपोज़ेबल, ऐसा कंपोज़ेबल होता है जो कोई स्टेट होल्ड नहीं करता. स्टेटलेस कंपोज़ेबल बनाने का एक आसान तरीका है, स्टेट होइस्टिंग का इस्तेमाल करना.
फिर से इस्तेमाल किए जा सकने वाले कंपोज़ेबल डेवलप करते समय, अक्सर एक ही कंपोज़ेबल का स्टेटफ़ुल और स्टेटलेस, दोनों वर्शन दिखाना होता है. स्टेटफ़ुल वर्शन उन कॉलर के लिए काम का होता है जिन्हें स्टेट की परवाह नहीं होती. वहीं, स्टेटलेस वर्शन उन कॉलर के लिए ज़रूरी होता है जिन्हें स्टेट को कंट्रोल या होइस्ट करना होता है.
स्टेट होइस्टिंग
Compose में स्टेट होइस्टिंग, स्टेट को कंपोज़ेबल के कॉलर पर ले जाने का एक पैटर्न है. इससे कंपोज़ेबल स्टेटलेस बन जाता है. Jetpack Compose में स्टेट होइस्टिंग का सामान्य पैटर्न, स्टेट वैरिएबल को इन दो पैरामीटर से बदलना है:
value: T: दिखाने के लिए मौजूदा वैल्यूonValueChange: (T) -> Unit: एक ऐसा इवेंट जो वैल्यू में बदलाव करने का अनुरोध करता है, इसमेंTप्रस्तावित नई वैल्यू है
हालांकि, आपके पास सिर्फ़ onValueChange का इस्तेमाल करने का विकल्प नहीं है. अगर कंपोज़ेबल के लिए ज़्यादा खास इवेंट सही हैं, तो उन्हें लैम्डा का इस्तेमाल करके तय करें.
इस तरह होइस्ट की गई स्टेट में कुछ अहम प्रॉपर्टी होती हैं:
- एकमात्र भरोसेमंद सोर्स: स्टेट को डुप्लीकेट करने के बजाय, उसे मूव करके हम यह पक्का करते हैं कि सिर्फ़ एक भरोसेमंद सोर्स हो. इससे बग से बचने में मदद मिलती है.
- एनकैप्सुलेटेड: सिर्फ़ स्टेटफ़ुल कंपोज़ेबल अपनी स्टेट में बदलाव कर सकते हैं. यह पूरी तरह से इंटरनल होता है.
- शेयर किया जा सकता है: होइस्ट की गई स्टेट को कई कंपोज़ेबल के साथ शेयर किया जा सकता है. अगर आपको किसी दूसरे कंपोज़ेबल में
nameको पढ़ना है, तो होइस्टिंग की मदद से ऐसा किया जा सकता है. - इंटरसेप्ट किया जा सकता है: स्टेटलेस कंपोज़ेबल के कॉलर, स्टेट में बदलाव करने से पहले इवेंट को अनदेखा या उनमें बदलाव कर सकते हैं.
- डिकपल किया गया: स्टेटलेस कंपोज़ेबल के लिए स्टेट को कहीं भी स्टोर किया जा सकता है. उदाहरण के लिए, अब
nameकोViewModelमें ले जाना मुमकिन है.
उदाहरण के तौर पर, HelloContent से name और onValueChange को निकालकर, उन्हें ट्री में ऊपर की ओर HelloScreen कंपोज़ेबल में ले जाएं. यह कंपोज़ेबल, HelloContent को कॉल करता है.
@Composable fun HelloScreen() { var name by rememberSaveable { mutableStateOf("") } HelloContent(name = name, onNameChange = { name = it }) } @Composable fun HelloContent(name: String, onNameChange: (String) -> Unit) { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Hello, $name", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) OutlinedTextField(value = name, onValueChange = onNameChange, label = { Text("Name") }) } }
HelloContent से स्टेट को होइस्ट करने पर, कंपोज़ेबल के बारे में तर्क देना, उसे अलग-अलग स्थितियों में फिर से इस्तेमाल करना, और उसे टेस्ट करना आसान हो जाता है. HelloContent , अपनी स्टेट को स्टोर करने के तरीके से डिकपल हो जाता है. डिकपल करने का मतलब है कि अगर HelloScreen में बदलाव किया जाता है या उसे बदला जाता है, तो आपको HelloContent को लागू करने के तरीके में बदलाव नहीं करना पड़ता.
जिस पैटर्न में स्टेट नीचे की ओर जाती है और इवेंट ऊपर की ओर जाते हैं उसे यूनिडायरेक्शनल डेटा फ़्लो कहते हैं. इस मामले में, स्टेट HelloScreen से HelloContent की ओर जाती है और इवेंट HelloContent से HelloScreen की ओर जाते हैं. यूनिडायरेक्शनल डेटा फ़्लो को फ़ॉलो करके, यूज़र इंटरफ़ेस (यूआई) में स्टेट दिखाने वाले कंपोज़ेबल को अपने ऐप्लिकेशन के उन हिस्सों से डिकपल किया जा सकता है जो स्टेट को स्टोर और उसमें बदलाव करते हैं.
ज़्यादा जानने के लिए, स्टेट को कहां होइस्ट करें पेज देखें.
Compose में स्टेट को वापस लाना
The rememberSaveable एपीआई, remember की तरह काम करता है, क्योंकि यह
रीकंपोज़िशन के दौरान स्टेट को बनाए रखता है. साथ ही, गतिविधि या प्रोसेस
को फिर से बनाने के दौरान भी स्टेट को बनाए रखता है. उदाहरण के लिए, ऐसा तब होता है, जब स्क्रीन को घुमाया जाता है.
स्टेट को स्टोर करने के तरीके
Bundle में जोड़ा गया सभी डेटा टाइप अपने-आप सेव हो जाता है. अगर आपको कुछ ऐसा सेव करना है जिसे Bundle में नहीं जोड़ा जा सकता, तो आपके पास कई विकल्प हैं.
Parcelize
सबसे आसान तरीका है कि ऑब्जेक्ट में
@Parcelize
एनोटेशन जोड़ा जाए. ऑब्जेक्ट पार्सल किया जा सकता है और उसे बंडल किया जा सकता है. उदाहरण के लिए, इस कोड से पार्सल किया जा सकने वाला City डेटा टाइप बनता है और यह स्टेट में सेव हो जाता है.
@Parcelize data class City(val name: String, val country: String) : Parcelable @Composable fun CityScreen() { var selectedCity = rememberSaveable { mutableStateOf(City("Madrid", "Spain")) } }
MapSaver
अगर किसी वजह से @Parcelize सही नहीं है, तो mapSaver का इस्तेमाल करके, किसी ऑब्जेक्ट को वैल्यू के सेट में बदलने के लिए अपना नियम तय किया जा सकता है. सिस्टम, इन वैल्यू को Bundle में सेव कर सकता है.
data class City(val name: String, val country: String) val CitySaver = run { val nameKey = "Name" val countryKey = "Country" mapSaver( save = { mapOf(nameKey to it.name, countryKey to it.country) }, restore = { City(it[nameKey] as String, it[countryKey] as String) } ) } @Composable fun CityScreen() { var selectedCity = rememberSaveable(stateSaver = CitySaver) { mutableStateOf(City("Madrid", "Spain")) } }
ListSaver
मैप के लिए कुंजियां तय करने से बचने के लिए, listSaver का इस्तेमाल भी किया जा सकता है. साथ ही, इसके इंडेक्स को कुंजियों के तौर पर इस्तेमाल किया जा सकता है:
data class City(val name: String, val country: String) val CitySaver = listSaver<City, Any>( save = { listOf(it.name, it.country) }, restore = { City(it[0] as String, it[1] as String) } ) @Composable fun CityScreen() { var selectedCity = rememberSaveable(stateSaver = CitySaver) { mutableStateOf(City("Madrid", "Spain")) } }
Compose में स्टेट होल्डर
स्टेट होइस्टिंग को कंपोज़ेबल फ़ंक्शन में ही मैनेज किया जा सकता है. हालांकि, अगर ट्रैक किए जाने वाली स्टेट की संख्या बढ़ जाती है या कंपोज़ेबल फ़ंक्शन में लॉजिक लागू करने की ज़रूरत पड़ती है, तो लॉजिक और स्टेट की ज़िम्मेदारियों को अन्य क्लास को सौंपना एक अच्छा तरीका है. इन क्लास को स्टेट होल्डर कहा जाता है.
ज़्यादा जानने के लिए, Compose में स्टेट होइस्टिंग के बारे में दस्तावेज़ देखें. इसके अलावा, आर्किटेक्चर गाइड में स्टेट होल्डर और यूज़र इंटरफ़ेस (यूआई) स्टेट पेज देखें.
कुंजियों में बदलाव होने पर, remember की कैलकुलेशन को फिर से ट्रिगर करना
remember एपीआई का इस्तेमाल अक्सर MutableState के साथ किया जाता है:
var name by remember { mutableStateOf("") }
यहां, remember फ़ंक्शन का इस्तेमाल करने से, MutableState की वैल्यू, रीकंपोज़िशन के दौरान बनी रहती है.
आम तौर पर, remember, calculation लैम्डा पैरामीटर लेता है. जब remember पहली बार चलता है, तो यह calculation लैम्डा को लागू करता है और उसके नतीजे को स्टोर करता है. रीकंपोज़िशन के दौरान, remember वह वैल्यू दिखाता है जो पिछली बार स्टोर की गई थी.
स्टेट को कैश में सेव करने के अलावा, remember का इस्तेमाल, कंपोज़िशन में किसी भी ऐसे ऑब्जेक्ट या ऑपरेशन के नतीजे को स्टोर करने के लिए भी किया जा सकता है जिसे शुरू करने या कैलकुलेट करने में ज़्यादा समय लगता है. हो सकता है कि आपको हर रीकंपोज़िशन में इस कैलकुलेशन को दोहराना न पड़े.
इसका एक उदाहरण, इस ShaderBrush ऑब्जेक्ट को बनाना है. यह एक महंगा
ऑपरेशन है:
val brush = remember { ShaderBrush( BitmapShader( ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT ) ) }
remember, वैल्यू को तब तक स्टोर करता है, जब तक वह कंपोज़िशन से बाहर नहीं निकल जाती. हालांकि, कैश में सेव की गई वैल्यू को अमान्य करने का एक तरीका है. remember एपीआई, key या
keys पैरामीटर भी लेता है. अगर इनमें से कोई भी कुंजी बदलती है, तो अगली बार जब फ़ंक्शन
रीकंपोज़ होता है, remember कैश को अमान्य कर देता है और कैलकुलेशन
लैम्डा ब्लॉक को फिर से लागू करता है. इस मैकेनिज़्म से, कंपोज़िशन में किसी ऑब्जेक्ट के लाइफ़टाइम को कंट्रोल किया जा सकता है. कैलकुलेशन तब तक मान्य रहती है, जब तक इनपुट में बदलाव नहीं होता. ऐसा तब तक नहीं होता, जब तक याद रखी गई वैल्यू कंपोज़िशन से बाहर नहीं निकल जाती.
यहां दिए गए उदाहरणों से पता चलता है कि यह मैकेनिज़्म कैसे काम करता है.
इस स्निपेट में, एक ShaderBrush बनाया गया है और इसे बैकग्राउंड
पेंट के तौर पर एक Box कंपोज़ेबल के तौर पर इस्तेमाल किया गया है. remember ShaderBrush इंस्टेंस को स्टोर करता है, क्योंकि इसे फिर से बनाना महंगा होता है. इसके बारे में पहले बताया जा चुका है. remember, avatarRes को key1 पैरामीटर के तौर पर लेता है. यह चुनी गई बैकग्राउंड इमेज है. अगर avatarRes में बदलाव होता है, तो ब्रश नई इमेज के साथ रीकंपोज़ होता है और Box पर फिर से लागू होता है. ऐसा तब हो सकता है, जब उपयोगकर्ता, पिकर से बैकग्राउंड के तौर पर इस्तेमाल करने के लिए कोई दूसरी इमेज चुनता है.
@Composable private fun BackgroundBanner( @DrawableRes avatarRes: Int, modifier: Modifier = Modifier, res: Resources = LocalContext.current.resources ) { val brush = remember(key1 = avatarRes) { ShaderBrush( BitmapShader( ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT ) ) } Box( modifier = modifier.background(brush) ) { /* ... */ } }
अगले स्निपेट में, स्टेट को सामान्य स्टेट होल्डर क्लास
MyAppState पर होइस्ट किया गया है. यह rememberMyAppState फ़ंक्शन को, क्लास का इंस्टेंस शुरू करने के लिए remember का इस्तेमाल करके दिखाता है. ऐसे फ़ंक्शन को दिखाना, कंपोज़ में एक सामान्य पैटर्न है. इससे ऐसा इंस्टेंस बनाया जा सकता है जो रीकंपोज़िशन के दौरान बना रहता है.
rememberMyAppState फ़ंक्शन को windowSizeClass मिलता है. यह
key पैरामीटर के तौर पर काम करता है remember के लिए. अगर इस पैरामीटर में बदलाव होता है, तो ऐप्लिकेशन को सामान्य स्टेट होल्डर क्लास को नई वैल्यू के साथ फिर से बनाना होगा. उदाहरण के लिए, ऐसा तब हो सकता है, जब उपयोगकर्ता डिवाइस को घुमाता है.
@Composable private fun rememberMyAppState( windowSizeClass: WindowSizeClass ): MyAppState { return remember(windowSizeClass) { MyAppState(windowSizeClass) } } @Stable class MyAppState( private val windowSizeClass: WindowSizeClass ) { /* ... */ }
Compose, क्लास के equals लागू करने के तरीके का इस्तेमाल करके यह तय करता है कि कोई कुंजी बदली है या नहीं . साथ ही, यह स्टोर की गई वैल्यू को अमान्य कर देता है.
रीकंपोज़िशन के बाद भी, कुंजियों के साथ स्टेट को स्टोर करना
rememberSaveable एपीआई, remember के लिए रैपर है. यह
डेटा Bundle में स्टोर कर सकता है. इस एपीआई की मदद से, स्टेट न सिर्फ़ रीकंपोज़िशन के दौरान, बल्कि गतिविधि को फिर से बनाने और सिस्टम की ओर से शुरू की गई प्रोसेस के खत्म होने के दौरान भी बनी रहती है.
rememberSaveable उसी मकसद के लिए input पैरामीटर लेता है जिसके लिए
remember keys लेता है. जब किसी भी इनपुट में बदलाव होता है, तो कैश अमान्य हो जाता है. अगली बार जब फ़ंक्शन रीकंपोज़ होता है, तो rememberSaveable, कैलकुलेशन लैम्डा ब्लॉक को फिर से लागू करता है.
यहां दिए गए उदाहरण में, rememberSaveable, userTypedQuery को तब तक स्टोर करता है, जब तक typedQuery में बदलाव नहीं होता:
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
ज़्यादा जानें
स्टेट और Jetpack Compose के बारे में ज़्यादा जानने के लिए, ये अतिरिक्त संसाधन देखें.
सैंपल
कोडलैब
वीडियो
ब्लॉग
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर, लिंक का टेक्स्ट दिखता है
- Compose यूज़र इंटरफ़ेस (यूआई) का आर्किटेक्चर बनाना
- Compose में यूज़र इंटरफ़ेस (यूआई) स्टेट सेव करना
- Compose में साइड इफ़ेक्ट