Compose की सुविधा में इस्तेमाल किए जाने वाले ऐप्लिकेशन में यूज़र इंटरफ़ेस (यूआई) की स्थिति, इस बात पर निर्भर करती है कि यूज़र इंटरफ़ेस (यूआई) तर्क या बिज़नेस लॉजिक के लिए यह ज़रूरी है. इस दस्तावेज़ में, इन दो मुख्य बातों के बारे में बताया गया है .
सबसे सही तरीका
आपको यूज़र इंटरफ़ेस (यूआई) स्थिति को उन सभी पेजों के बीच सबसे कम सामान्य पूर्वज पर रखना चाहिए कंपोज़ेबल जो उसे पढ़ें और लिखें. राज्य को जहां वह है उसके पास ही रखना चाहिए खर्च किए गए हों. राज्य के मालिक की ओर से, उपभोक्ताओं को नहीं बदले जा सकने वाले स्टेटस और इवेंट के बारे में बताएं राज्य में बदलाव करने के लिए.
सबसे कम कॉमन ऐन्सेस्टर, कंपोज़िशन से बाहर भी हो सकता है. उदाहरण के लिए,
ViewModel
में स्थिति को हाइलाइट करते समय, कारोबारी नियम शामिल होता है.
इस पेज पर इस सबसे सही तरीके के बारे में विस्तार से बताया गया है और ध्यान रखने वाली एक चेतावनी दी गई है.
यूज़र इंटरफ़ेस (यूआई) की स्थिति और यूज़र इंटरफ़ेस (यूआई) लॉजिक के टाइप
यूज़र इंटरफ़ेस (यूआई) की स्थिति और इस्तेमाल किए जाने वाले लॉजिक की परिभाषाएं नीचे दी गई हैं पूरा दस्तावेज़ पढ़ें.
यूज़र इंटरफ़ेस (यूआई) की स्थिति
यूज़र इंटरफ़ेस (यूआई) की स्थिति वह प्रॉपर्टी है जो यूज़र इंटरफ़ेस (यूआई) की जानकारी देती है. यूज़र इंटरफ़ेस (यूआई) दो तरह के होते हैं राज्य:
- स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति: इसका मतलब है कि आपको स्क्रीन पर क्या दिखाना है. उदाहरण के लिए,
NewsUiState
क्लास में ज़रूरी समाचार और अन्य जानकारी शामिल हो सकती है का इस्तेमाल करें. यह स्थिति आम तौर पर क्योंकि इसमें ऐप्लिकेशन का डेटा शामिल है. - यूज़र इंटरफ़ेस (यूआई) एलिमेंट की स्थिति, यूज़र इंटरफ़ेस (यूआई) एलिमेंट से जुड़ी प्रॉपर्टी के बारे में बताती है
और उन्हें रेंडर करने के तरीके पर असर डाल सकते हैं. यूज़र इंटरफ़ेस (यूआई) एलिमेंट दिखाया या छिपाया जा सकता है और
फ़ॉन्ट, साइज़ या फ़ॉन्ट के लिए एक तय रंग होना चाहिए. Android व्यू में, व्यू
इस स्थिति को खुद प्रबंधित करती है, क्योंकि यह स्वाभाविक रूप से राज्य से जुड़ी होती है. साथ ही,
इसकी स्थिति में बदलाव करें या उसके बारे में क्वेरी करें. उदाहरण के लिए,
get
औरTextView
क्लास के टेक्स्ट के लिएset
तरीके. Jetpack में कंपोज़ेबल में कंपोज़ की गई स्थिति से बाहर का रास्ता होता है और उसे इधर-उधर ले जाया जा सकता है यह कॉम्पोनेंट, कंपोज़ेबल के आस-पास मौजूद नहीं है फ़ंक्शन या स्टेट होल्डर के रूप में दी जाती है. इसका एक उदाहरणScaffoldState
है, जिसमेंScaffold
कंपोज़ेबल.
तर्क वाले गेम
किसी ऐप्लिकेशन में लॉजिक, बिज़नेस लॉजिक या यूज़र इंटरफ़ेस (यूआई) लॉजिक हो सकता है:
- कारोबार का नियम, ऐप्लिकेशन के लिए प्रॉडक्ट से जुड़ी ज़रूरी शर्तों को लागू करने का तरीका है डेटा शामिल है. उदाहरण के लिए, जब उपयोगकर्ता किसी लेख को न्यूज़ रीडर ऐप्लिकेशन में बुकमार्क करता है बटन पर टैप करता है. किसी फ़ाइल या डेटाबेस में बुकमार्क सेव करने का यह लॉजिक है आम तौर पर, डोमेन या डेटा लेयर में रखी जाती हैं. स्टेट होल्डर आम तौर पर इस लॉजिक को उन लेयर को असाइन करता है जिन्हें वे दिखाते हैं.
- यूज़र इंटरफ़ेस (यूआई) लॉजिक, स्क्रीन पर यूआई स्थिति दिखाने के तरीके से जुड़ा होता है. इसके लिए उदाहरण के लिए, सही खोज बार संकेत पाने के लिए, जब उपयोगकर्ता ने किसी कैटगरी, सूची में किसी खास आइटम पर स्क्रोल करना या नेविगेशन लॉजिक किसी बटन पर क्लिक करने पर, किसी खास स्क्रीन पर विज्ञापन दिखाने के लिए.
यूज़र इंटरफ़ेस (यूआई) लॉजिक
जब यूज़र इंटरफ़ेस (यूआई) लॉजिक को स्टेटस पढ़ने या उसमें बदलाव करने की ज़रूरत हो, तो आपको स्टेटस को उसके लाइफ़साइकल के हिसाब से यूज़र इंटरफ़ेस (यूआई) का स्कोप करना चाहिए. इसे पाने के लिए, आपको कंपोज़ेबल फ़ंक्शन में राज्य को सही लेवल पर रखना चाहिए. इसके अलावा, आपके पास ये विकल्प हैं इसे प्लेन स्टेट होल्डर क्लास में भी किया जा सकता है. इसे यूज़र इंटरफ़ेस (यूआई) लाइफ़साइकल के दायरे में भी लाया जा सकता है.
नीचे दोनों समाधानों का वर्णन दिया गया है और बताया गया है कि कब उपयोग करना चाहिए.
राज्य के मालिक के तौर पर कंपोज़ेबल
कंपोज़ेबल में यूआई लॉजिक और यूज़र इंटरफ़ेस (यूआई) एलिमेंट की स्थिति का इस्तेमाल करना एक अच्छा तरीका है, अगर राज्य और तर्क आसान है. अपने राज्य को इंटरनल कंपोज़ेबल या कंपोज़ेबल में छोड़ा जा सकता है ज़रूरत के हिसाब से लिफ़्ट किया जा सकता है.
राज्य स्तर पर लिफ़्ट करने की ज़रूरत नहीं है
लिफ़्टिंग स्टेट की हमेशा ज़रूरत नहीं होती है. स्थिति को किसी कंपोज़ेबल में अंदरूनी रखा जा सकता है जब किसी अन्य कंपोज़ेबल को इसे कंट्रोल करने की ज़रूरत न हो. इस स्निपेट में, एक ऐसा कंपोज़ेबल है जो टैप करने पर बड़ा और छोटा होता है:
@Composable fun ChatBubble( message: Message ) { var showDetails by rememberSaveable { mutableStateOf(false) } // Define the UI element expanded state ClickableText( text = AnnotatedString(message.content), onClick = { showDetails = !showDetails } // Apply simple UI logic ) if (showDetails) { Text(message.timestamp) } }
वैरिएबल showDetails
, इस यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए अंदरूनी स्थिति है. बस
इस कंपोज़ेबल में रीड और मॉडिफ़िकेशन किया गया है. साथ ही, इस पर लागू किया गया लॉजिक बहुत आसान है.
इसलिए, इस मामले में राज्य को हटाने से कोई खास फ़ायदा नहीं होगा. इसलिए, आपको
उसे अंदरूनी रहने दें. ऐसा करने से, यह कंपोज़ेबल मालिक और सिंगल बन जाता है
की सच्चाई का पता लगाना ज़रूरी है.
कंपोज़ेबल में रिकॉर्ड करना
अगर आपको अपने यूज़र इंटरफ़ेस (यूआई) एलिमेंट की स्थिति को अन्य कंपोज़ेबल के साथ शेयर करना है और यूज़र इंटरफ़ेस (यूआई) लागू करना है, तो पर रखना चाहते हैं, तो आप इसे यूज़र इंटरफ़ेस (यूआई) हैरारकी में ऊपर उठा सकते हैं. इससे कंपोज़ेबल को फिर से इस्तेमाल करने लायक और टेस्ट करने में आसानी होती है.
नीचे दिए गए उदाहरण में, एक ऐसे चैट ऐप्लिकेशन का उदाहरण दिया गया है जिसमें ये दो सुविधाएं लागू की गई हैं:
JumpToBottom
बटन, मैसेज की सूची को स्क्रोल करके सबसे नीचे ले जाता है. बटन सूची की स्थिति पर यूज़र इंटरफ़ेस (यूआई) लॉजिक का इस्तेमाल करता है.- उपयोगकर्ता के नए ईमेल भेजने के बाद,
MessagesList
सूची नीचे की ओर स्क्रोल होती है मैसेज. Userइनपुट, सूची की स्थिति पर यूज़र इंटरफ़ेस (यूआई) लॉजिक का इस्तेमाल करता है.
![जंपToBottom बटन की मदद से, चैट ऐप्लिकेशन खोलें और नए मैसेज पर स्क्रोल करके सबसे नीचे जाएं](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-chat.png?authuser=5&hl=hi)
JumpToBottom
बटन की मदद से चैट ऐप्लिकेशन और नए मैसेज के सबसे नीचे तक स्क्रोल करनाकंपोज़ेबल हैरारकी इस तरह है:
![चैट कंपोज़ेबल ट्री](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-initial-tree.png?authuser=5&hl=hi)
LazyColumn
की स्थिति को बातचीत वाली स्क्रीन पर ले जाया जाता है, ताकि ऐप्लिकेशन ये काम कर सके
यूज़र इंटरफ़ेस (यूआई) लॉजिक का इस्तेमाल करें और उन सभी कंपोज़ेबल में स्टेटस को पढ़ें जिनके लिए इसकी ज़रूरत है:
![LaZकॉलम से बातचीत स्क्रीन पर LazyColumn की स्थिति दिखाने का तरीका](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-animated.gif?authuser=5&hl=hi)
LazyColumn
स्थिति को LazyColumn
से ConversationScreen
पर ले जाया जा रहा हैइसलिए, कुल मिलाकर ये कंपोज़ेबल हैं:
![लेज़ीलिस्टस्टेट के साथ चैट कंपोज़ेबल ट्री को ConversationScreen पर ले जाया गया](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-passing-state.png?authuser=5&hl=hi)
LazyListState
के साथ चैट कंपोज़ेबल ट्री, ConversationScreen
पर पहुंच गयाकोड इस तरह से होता है:
@Composable private fun ConversationScreen(/*...*/) { val scope = rememberCoroutineScope() val lazyListState = rememberLazyListState() // State hoisted to the ConversationScreen MessagesList(messages, lazyListState) // Reuse same state in MessageList UserInput( onMessageSent = { // Apply UI logic to lazyListState scope.launch { lazyListState.scrollToItem(0) } }, ) } @Composable private fun MessagesList( messages: List<Message>, lazyListState: LazyListState = rememberLazyListState() // LazyListState has a default value ) { LazyColumn( state = lazyListState // Pass hoisted state to LazyColumn ) { items(messages, key = { message -> message.id }) { item -> Message(/*...*/) } } val scope = rememberCoroutineScope() JumpToBottom(onClicked = { scope.launch { lazyListState.scrollToItem(0) // UI logic being applied to lazyListState } }) }
LazyListState
को यूज़र इंटरफ़ेस (यूआई) लॉजिक के लिए ज़रूरत के मुताबिक ऊंचा किया गया है.
लागू किया गया. इसे कंपोज़ेबल फ़ंक्शन में शुरू किया गया है, इसलिए इसे
कंपोज़िशन, लाइफ़साइकल के हिसाब से.
ध्यान दें कि lazyListState
को MessagesList
तरीके में तय किया गया है. इसमें
rememberLazyListState()
की डिफ़ॉल्ट वैल्यू. यह Compose में आम तौर पर इस्तेमाल किया जाने वाला पैटर्न है.
यह कंपोज़ेबल को फिर से इस्तेमाल करने लायक और सुविधाजनक बनाता है. इसके बाद, कंपोज़ेबल का इस्तेमाल किया जा सकता है
अलग-अलग हिस्सों में किए जा सकते हैं, जिनके लिए शायद राज्य को कंट्रोल करने की ज़रूरत न पड़े. यह है
यह आम तौर पर, कंपोज़ेबल की जांच या झलक देखते समय होता है. यह ठीक ऐसा ही है
LazyColumn
इसकी स्थिति के बारे में बताता है.
![LazyListState के लिए सबसे कम कॉमन एंसेस्टर](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-lca.png?authuser=5&hl=hi)
LazyListState
के लिए सबसे कम कॉमन ऐन्सेस्टर ConversationScreen
राज्य के मालिक के तौर पर सामान्य राज्य धारक की क्लास
जब किसी कंपोज़ेबल में जटिल यूज़र इंटरफ़ेस (यूआई) लॉजिक होता है और एक या एक से ज़्यादा स्टेट शामिल होते हैं फ़ील्ड में डाला गया है, तो उसे यह ज़िम्मेदारी सौंपी जानी चाहिए कि यह होल्डर, जैसे कि एक सामान्य राज्य धारक की क्लास. इससे कंपोज़ेबल का लॉजिक और इसकी जटिलता को कम करता है. इस तरीके से, सेपरेशन ऑफ़ एंट्रेंस सिद्धांत: कंपोज़ेबल का हिसाब लगाने के लिए, सबसे ज़रूरी है और स्टेट होल्डर में यूज़र इंटरफ़ेस (यूआई) लॉजिक और यूज़र इंटरफ़ेस (यूआई) शामिल होता है. एलिमेंट की स्थिति के हिसाब से.
प्लेन स्टेट होल्डर क्लास आपके कंपोज़ेबल फ़ंक्शन का इस्तेमाल किया जा सकता है, इसलिए उन्हें यह लॉजिक खुद लिखने की ज़रूरत नहीं होती.
इन सामान्य क्लास को कंपोज़िशन में बनाया और याद रखा जाता है. क्योंकि वे
कंपोज़ेबल के लाइफ़साइकल का पालन करता है, तो वे उससे जुड़े टाइप ले सकते हैं
rememberNavController()
या rememberLazyListState()
जैसी लाइब्रेरी लिखें.
इसका एक उदाहरण LazyListState
सादा राज्य का मालिक है
क्लास, जिसे LazyColumn
के यूज़र इंटरफ़ेस (यूआई) की जटिलता को कंट्रोल करने के लिए Compose में लागू किया गया है
या LazyRow
.
// LazyListState.kt @Stable class LazyListState constructor( firstVisibleItemIndex: Int = 0, firstVisibleItemScrollOffset: Int = 0 ) : ScrollableState { /** * The holder class for the current scroll position. */ private val scrollPosition = LazyListScrollPosition( firstVisibleItemIndex, firstVisibleItemScrollOffset ) suspend fun scrollToItem(/*...*/) { /*...*/ } override suspend fun scroll() { /*...*/ } suspend fun animateScrollToItem() { /*...*/ } }
LazyListState
, LazyColumn
को स्टोर करने की स्थिति को एनकैप्सुलेट करता है
इस यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए scrollPosition
. यह रिपोर्ट में बदलाव करने के
दाईं ओर स्क्रोल करें.
जैसा कि आपको दिख रहा है, किसी कंपोज़ेबल की ज़िम्मेदारी बढ़ाने से स्टेट होल्डर की ज़रूरत है. ज़िम्मेदारियां, यूज़र इंटरफ़ेस (यूआई) लॉजिक में या सिर्फ़ राज्य की मात्रा का ट्रैक रखना.
एक अन्य सामान्य पैटर्न, प्लेन स्टेट होल्डर क्लास का इस्तेमाल करता है ऐप्लिकेशन में रूट कंपोज़ेबल फ़ंक्शन की जटिलता बताई गई हो. ऐसी क्लास का इस्तेमाल इन कामों के लिए किया जा सकता है ऐप्लिकेशन-लेवल की स्थिति को एनकैप्सुलेट करें, जैसे कि नेविगेशन स्टेटस और स्क्रीन के साइज़. पूरा इसकी जानकारी, यूज़र इंटरफ़ेस (यूआई) लॉजिक और इसके मालिक की स्थिति वाले पेज में देखी जा सकती है.
बिज़नेस लॉजिक
अगर कंपोज़ेबल और प्लेन स्टेट होल्डर क्लास में यूज़र इंटरफ़ेस (यूआई) लॉजिक और यूज़र इंटरफ़ेस (यूआई) एलिमेंट की स्थिति, स्क्रीन लेवल का स्टेटस होल्डर इन चीज़ों को मैनेज करता है टास्क:
- ऐप्लिकेशन के बिज़नेस लॉजिक का ऐक्सेस देना आम तौर पर, उन्हें क्रम के हिसाब से अन्य लेयर में रखा जाता है, जैसे कि कारोबार और डेटा लेयर में.
- किसी खास स्क्रीन पर प्रज़ेंटेशन के लिए, ऐप्लिकेशन का डेटा तैयार किया जा रहा है, जो कि स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति बन जाता है.
राज्य के मालिक के तौर पर ViewModels
Android डेवलपमेंट में AAC ViewModels के फ़ायदे उन्हें सही बनाते हैं, जो बिज़नेस लॉजिक का ऐक्सेस देने और ऐप्लिकेशन का डेटा तैयार करने के लिए स्क्रीन पर प्रज़ेंटेशन के लिए.
ViewModel
में यूज़र इंटरफ़ेस (यूआई) स्थिति को रखने पर, उसे
कंपोज़िशन.
![ViewModel पर फ़ेच किया गया स्टेट, कंपोज़िशन के बाहर सेव है.](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-vm.png?authuser=5&hl=hi)
ViewModel
पर होस्ट किया गया राज्य, कंपोज़िशन के बाहर सेव है.ViewModels, कंपोज़िशन के हिस्से के तौर पर सेव नहीं किए जाते. इन्हें पब्लिशर,
फ़्रेमवर्क उपलब्ध कराया जाता है और उनका दायरा ViewModelStoreOwner
तक सीमित होता है. यह
नेविगेशन ग्राफ़ की गतिविधि, फ़्रैगमेंट, नेविगेशन ग्राफ़ या डेस्टिनेशन. इसके लिए
ViewModel
के दायरे के बारे में ज़्यादा जानकारी के लिए, दस्तावेज़ देखा जा सकता है.
इसके बाद, ViewModel
सबसे सत्य और सबसे कम पूर्वज है
यूज़र इंटरफ़ेस (यूआई) की स्थिति.
स्क्रीन यूज़र इंटरफ़ेस (यूआई) की स्थिति
ऊपर दी गई परिभाषा के मुताबिक, स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति, कारोबार की जानकारी लागू करने पर जनरेट होती है
नियम. यह देखते हुए कि स्क्रीन लेवल का स्टेटस होल्डर इसके लिए ज़िम्मेदार है
इसका मतलब है कि स्क्रीन यूज़र इंटरफ़ेस (यूआई) की स्थिति को आम तौर पर स्क्रीन लेवल की स्थिति में दिखाया जाता है
धारक, इस मामले में ViewModel
.
चैट ऐप्लिकेशन के ConversationViewModel
को ध्यान में रखें. साथ ही, यह देखें कि यह स्क्रीन कैसे दिखाता है
यूज़र इंटरफ़ेस (यूआई) की स्थिति और इवेंट में बदलाव करने के लिए:
class ConversationViewModel( channelId: String, messagesRepository: MessagesRepository ) : ViewModel() { val messages = messagesRepository .getLatestMessages(channelId) .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = emptyList() ) // Business logic fun sendMessage(message: Message) { /* ... */ } }
कंपोज़ेबल, ViewModel
में लिफ़्ट की गई स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति का इस्तेमाल करते हैं. आपको ऐसा करना चाहिए
स्क्रीन-लेवल के कंपोज़ेबल में ViewModel
इंस्टेंस इंजेक्ट करें, ताकि
कारोबारी नियम ऐक्सेस करने की सुविधा.
स्क्रीन-लेवल कंपोज़ेबल में इस्तेमाल किए गए ViewModel
का उदाहरण नीचे दिया गया है.
यहां कंपोज़ेबल ConversationScreen()
, लिफ़्ट की गई स्क्रीन के यूज़र इंटरफ़ेस (यूआई) स्थिति का इस्तेमाल करता है
ViewModel
में:
@Composable private fun ConversationScreen( conversationViewModel: ConversationViewModel = viewModel() ) { val messages by conversationViewModel.messages.collectAsStateWithLifecycle() ConversationScreen( messages = messages, onSendMessage = { message: Message -> conversationViewModel.sendMessage(message) } ) } @Composable private fun ConversationScreen( messages: List<Message>, onSendMessage: (Message) -> Unit ) { MessagesList(messages, onSendMessage) /* ... */ }
प्रॉपर्टी ड्रिलिंग
“प्रॉपर्टी की ड्रिलिंग” का मतलब है, नेस्ट किए गए कई चाइल्ड पब्लिशर के डेटा को एक जगह से दूसरी जगह भेजना कॉम्पोनेंट को पढ़ें.
इसका एक आम उदाहरण यह है कि कंपोज़ में प्रॉपर्टी की ड्रिलिंग कहां दिख सकती है, टॉप लेवल पर स्क्रीन लेवल स्टेट होल्डर को इंजेक्ट करें और पास डाउन होने की स्थिति में बच्चों के कंपोज़ेबल के लिए इवेंट. इससे, कंपोज़ेबल फ़ंक्शन सिग्नेचर.
हालांकि, इवेंट को अलग-अलग Lambda पैरामीटर के तौर पर दिखाने पर, फ़ंक्शन सिग्नेचर के साथ, इससे कंपोज़ेबल फ़ंक्शन को ज़्यादा से ज़्यादा लोगों को दिखाया जाता है ये ज़िम्मेदारी हैं. एक नज़र में देखा जा सकता है कि यह क्या करता है.
एनकैप्सुलेट के लिए रैपर क्लास बनाने की तुलना में प्रॉपर्टी ड्रिलिंग बेहतर है में एक ही जगह पर होने की वजह से, ज़िम्मेदारियां पूरी होती हैं. रैपर क्लास न होने से आपको और भी फ़ायदे मिलते हैं इस बात की संभावना है कि कंपोज़ेबल को सिर्फ़ अपने लिए ज़रूरी पैरामीटर पास किए जाएं, जो कि सबसे बढ़िया प्रैक्टिस करें.
अगर ये इवेंट नेविगेशन इवेंट हैं, तो भी सबसे सही यही तरीका लागू होता है. इसके बारे में ज़्यादा जानने के लिए, नेविगेशन वाले दस्तावेज़ देखें.
अगर आपने परफ़ॉर्मेंस से जुड़ी किसी समस्या का पता लगाया है, तो आपके पास पढ़ने को रोकने का विकल्प भी है राज्य का है. ज़्यादा जानने के लिए, परफ़ॉर्मेंस दस्तावेज़ देखें.
यूज़र इंटरफ़ेस (यूआई) एलिमेंट की स्थिति
अगर स्क्रीन लेवल की स्थिति मौजूद है, तो यूआई एलिमेंट की स्थिति को स्क्रीन पर दिखाया जा सकता है बिज़नेस लॉजिक जिसे उसे पढ़ने या लिखने की ज़रूरत होती है.
चैट ऐप्लिकेशन के उदाहरण में, ऐप्लिकेशन उपयोगकर्ता के सुझाव
ग्रुप चैट, जब उपयोगकर्ता @
टाइप करता है और संकेत देता है. ये सुझाव
डेटा लेयर और उपयोगकर्ता के सुझावों की सूची को कैलकुलेट करने के लॉजिक को ध्यान में रखा जाता है
कारोबारी नियम. सुविधा इस तरह दिखती है:
![यह सुविधा, जब उपयोगकर्ता `@` और संकेत टाइप करता है, तो ग्रुप चैट में उपयोगकर्ता के सुझाव दिखाती है](https://developer.android.com/static/develop/ui/compose/images/state-hoisting-suggestions.png?authuser=5&hl=hi)
@
टाइप करता है और कोई संकेत टाइप करता है, तो ग्रुप चैट में सुझाव दिखाए जाते हैंइस सुविधा को लागू करने वाला ViewModel
ऐसा दिखेगा:
class ConversationViewModel(/*...*/) : ViewModel() { // Hoisted state var inputMessage by mutableStateOf("") private set val suggestions: StateFlow<List<Suggestion>> = snapshotFlow { inputMessage } .filter { hasSocialHandleHint(it) } .mapLatest { getHandle(it) } .mapLatest { repository.getSuggestions(it) } .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = emptyList() ) fun updateInput(newInput: String) { inputMessage = newInput } }
inputMessage
एक वैरिएबल है, जो TextField
स्थिति को स्टोर करता है. हर बार
नए इनपुट में उपयोगकर्ता टाइप का इस्तेमाल करते हैं, तो ऐप्लिकेशन suggestions
बनाने के लिए बिज़नेस लॉजिक का इस्तेमाल करता है.
suggestions
, स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति है और इसे 'लिखें' यूज़र इंटरफ़ेस (यूआई) में इस्तेमाल किया जा सकता है. इसके लिए, जानकारी इकट्ठा करें
StateFlow
से.
चेतावनी
'लिखें' यूज़र इंटरफ़ेस (यूआई) एलिमेंट की कुछ स्थितियों के लिए, ViewModel
पर ले जाने की ज़रूरत पड़ सकती है
ध्यान रखें. उदाहरण के लिए, Compose के यूज़र इंटरफ़ेस (यूआई) एलिमेंट के स्टेट होल्डर
स्टेट को बदलने का तरीका बताता है. इनमें से कुछ ऐसे फ़ंक्शन निलंबित हो सकते हैं जो
ऐनिमेशन ट्रिगर करने के लिए. अगर कॉल किया जाता है, तो इन निलंबित फ़ंक्शन को अपवाद माना जा सकता है
उन्हें CoroutineScope
से लिया गया है, जो
कंपोज़िशन.
मान लें कि ऐप्लिकेशन ड्रॉर का कॉन्टेंट डाइनैमिक है और आपको उसे फ़ेच और रीफ़्रेश करना है
डेटा लेयर से बाहर निकालने की सुविधा मिलती है. आपको पैनल की स्थिति को
ViewModel
, ताकि आप इस एलिमेंट के लिए यूज़र इंटरफ़ेस (यूआई) और बिज़नेस लॉजिक, दोनों को कॉल कर सकें
राज्य के मालिक से मिलता है.
हालांकि, DrawerState
के close()
तरीके को कॉल करने के लिए,
viewModelScope
'लिखें' यूज़र इंटरफ़ेस (यूआई) की वजह से, रनटाइम के दौरान टाइप का अपवाद होता है
IllegalStateException
जिसमें “a” मैसेज लिखा है
MonotonicFrameClock
इसमें उपलब्ध नहीं है
CoroutineContext”
.
इसे ठीक करने के लिए, कंपोज़िशन के CoroutineScope
के स्कोप का इस्तेमाल करें. यह
CoroutineContext
में MonotonicFrameClock
, जो
सस्पेंड फ़ंक्शन को काम पर ले जाता है.
इस क्रैश को ठीक करने के लिए, कोरूटीन के CoroutineContext
को
ViewModel
से लेकर कंपोज़िशन के दायरे में. यह ऐसा दिख सकता है:
class ConversationViewModel(/*...*/) : ViewModel() { val drawerState = DrawerState(initialValue = DrawerValue.Closed) private val _drawerContent = MutableStateFlow(DrawerContent.Empty) val drawerContent: StateFlow<DrawerContent> = _drawerContent.asStateFlow() fun closeDrawer(uiScope: CoroutineScope) { viewModelScope.launch { withContext(uiScope.coroutineContext) { // Use instead of the default context drawerState.close() } // Fetch drawer content and update state _drawerContent.update { content } } } } // in Compose @Composable private fun ConversationScreen( conversationViewModel: ConversationViewModel = viewModel() ) { val scope = rememberCoroutineScope() ConversationScreen(onCloseDrawer = { conversationViewModel.closeDrawer(uiScope = scope) }) }
ज़्यादा जानें
राज्य और Jetpack Compose के बारे में ज़्यादा जानने के लिए, ये देखें अतिरिक्त संसाधन शामिल करें.
सैंपल
कोड लैब
वीडियो
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- Compose में यूज़र इंटरफ़ेस (यूआई) की स्थिति सेव करना
- लिस्ट और ग्रिड
- अपना Compose यूज़र इंटरफ़ेस (यूआई) बनाना