ज़्यादातर अन्य यूज़र इंटरफ़ेस (यूआई) टूलकिट की तरह, Compose भी किसी फ़्रेम को कई अलग-अलग फ़ेज़ में रेंडर करता है. उदाहरण के लिए, Android व्यू सिस्टम में तीन मुख्य चरण होते हैं: मेज़र, लेआउट, और ड्रॉइंग. कॉम्पोज़ करने का तरीका बहुत हद तक एक जैसा है. हालांकि, इसमें शुरुआत में एक और अहम चरण होता है, जिसे कॉम्पोज़ेशन कहा जाता है.
Compose के दस्तावेज़ में, Compose के बारे में सोचना और स्टेट और Jetpack Compose में कॉम्पोज़िशन के बारे में बताया गया है.
फ़्रेम के तीन चरण
Compose में तीन मुख्य चरण होते हैं:
- कॉम्पोज़िशन: कौनसा यूज़र इंटरफ़ेस (यूआई) दिखाना है. Compose, कॉम्पोज़ेबल फ़ंक्शन चलाता है और आपके यूज़र इंटरफ़ेस (यूआई) की जानकारी बनाता है.
- लेआउट: यूज़र इंटरफ़ेस (यूआई) को कहां रखना है. इस चरण में दो चरण होते हैं: मेज़रमेंट और प्लेसमेंट. लेआउट एलिमेंट, लेआउट ट्री के हर नोड के लिए, खुद को और किसी भी चाइल्ड एलिमेंट को 2D निर्देशांक में मेज़र करते हैं और उन्हें प्लेस करते हैं.
- ड्रॉइंग: यह कैसे रेंडर होती है. यूज़र इंटरफ़ेस (यूआई) एलिमेंट, कैनवस में ड्रॉ किए जाते हैं. आम तौर पर, कैनवस डिवाइस की स्क्रीन होती है.

आम तौर पर, इन चरणों का क्रम एक जैसा होता है. इससे डेटा को एक दिशा में, कॉम्पोज़िशन से लेआउट और फिर ड्रॉइंग में भेजा जा सकता है, ताकि फ़्रेम बनाया जा सके. इसे एकतरफ़ा डेटा फ़्लो भी कहा जाता है. BoxWithConstraints
, LazyColumn
, और LazyRow
, ऐसे खास एक्सेप्शन हैं जिनमें चाइल्ड एलिमेंट का कॉम्पोज़िशन, पैरंट एलिमेंट के लेआउट फ़ेज़ पर निर्भर करता है.
कॉन्सेप्ट के हिसाब से, ये सभी फ़ेज़ हर फ़्रेम के लिए होते हैं. हालांकि, परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, Compose उस काम को दोहराने से बचता है जो इन सभी फ़ेज़ में एक ही इनपुट से एक ही नतीजे देता है. अगर Compose, पहले के नतीजे का फिर से इस्तेमाल कर सकता है, तो वह कॉम्पोज़ किए जा सकने वाले फ़ंक्शन को स्किप कर देता है. साथ ही, Compose का यूज़र इंटरफ़ेस (यूआई) ज़रूरत न होने पर, पूरे ट्री को फिर से लेआउट या फिर से नहीं बनाता. Compose, यूज़र इंटरफ़ेस (यूआई) को अपडेट करने के लिए, सिर्फ़ उतना ही काम करता है जितना ज़रूरी है. यह ऑप्टिमाइज़ेशन इसलिए होता है, क्योंकि Compose ट्रैक की स्थिति अलग-अलग चरणों में पढ़ी जाती है.
चरणों को समझना
इस सेक्शन में, कॉम्पोज़ेबल के लिए Compose के तीन चरणों को ज़्यादा जानकारी के साथ लागू करने का तरीका बताया गया है.
कंपोज़िशन
कॉम्पोज़िशन फ़ेज़ में, Compose रनटाइम, ऐप्लिकेशन बनाने की सुविधा वाले फ़ंक्शन को लागू करता है और आपके यूज़र इंटरफ़ेस (यूआई) को दिखाने वाला ट्री स्ट्रक्चर दिखाता है. इस यूज़र इंटरफ़ेस (यूआई) ट्री में लेआउट नोड होते हैं. इनमें अगले चरणों के लिए ज़रूरी सारी जानकारी होती है. इस बारे में यहां दिए गए वीडियो में बताया गया है:
दूसरी इमेज. कॉम्पोज़िशन फ़ेज़ में बनाए गए आपके यूज़र इंटरफ़ेस (यूआई) को दिखाने वाला ट्री.
कोड और यूज़र इंटरफ़ेस (यूआई) ट्री का एक सबसेक्शन ऐसा दिखता है:

इन उदाहरणों में, कोड में मौजूद हर कॉम्पोज़ेबल फ़ंक्शन, यूज़र इंटरफ़ेस (यूआई) ट्री में मौजूद एक लेआउट नोड से मैप होता है. ज़्यादा जटिल उदाहरणों में, कॉम्पोज़ेबल में लॉजिक और कंट्रोल फ़्लो हो सकता है. साथ ही, अलग-अलग स्थितियों के हिसाब से अलग-अलग ट्री जनरेट कर सकता है.
लेआउट
लेआउट फ़ेज़ में, Compose, कॉम्पोज़िशन फ़ेज़ में बनाए गए यूज़र इंटरफ़ेस (यूआई) ट्री का इस्तेमाल इनपुट के तौर पर करता है. लेआउट नोड के कलेक्शन में, 2D स्पेस में हर नोड के साइज़ और जगह तय करने के लिए ज़रूरी सारी जानकारी होती है.
चौथी इमेज. लेआउट फ़ेज़ के दौरान, यूज़र इंटरफ़ेस (यूआई) ट्री में हर लेआउट नोड का मेज़रमेंट और प्लेसमेंट.
लेआउट फ़ेज़ के दौरान, ट्री को तीन चरणों वाले एल्गोरिदम का इस्तेमाल करके ट्रैवर्स किया जाता है:
- चाइल्ड मेज़रमेंट: अगर कोई चाइल्ड मौजूद है, तो कोई नोड अपने चाइल्ड को मेज़र करता है.
- अपने साइज़ का फ़ैसला खुद करना: इन मेज़रमेंट के आधार पर, कोई नोड अपने साइज़ का फ़ैसला खुद करता है.
- चाइल्ड नोड डालना: हर चाइल्ड नोड को नोड की अपनी पोज़िशन के हिसाब से रखा जाता है.
इस फ़ेज़ के आखिर में, हर लेआउट नोड में ये चीज़ें होती हैं:
- असाइन की गई चौड़ाई और ऊंचाई
- x, y कोऑर्डिनेट, जहां इसे ड्रॉ किया जाना चाहिए
पिछले सेक्शन में दिए गए यूज़र इंटरफ़ेस ट्री को याद करें:
इस ट्री के लिए, एल्गोरिदम इस तरह काम करता है:
Row
, अपने चाइल्ड एलिमेंटImage
औरColumn
को मेज़र करता है.Image
को मेज़र किया जाता है. इसमें कोई चाइल्ड एलिमेंट नहीं है. इसलिए, यह अपने साइज़ का फ़ैसला खुद करता है और साइज़ की जानकारीRow
को देता है.- इसके बाद,
Column
को मेज़र किया जाता है. यह सबसे पहले अपने चाइल्ड (दोText
composables) को मेज़र करता है. - पहले
Text
को मेज़र किया जाता है. इसमें कोई बच्चा नहीं है, इसलिए यह अपने साइज़ का फ़ैसला खुद लेता है औरColumn
को अपने साइज़ की जानकारी देता है.- दूसरा
Text
मेज़र किया जाता है. इसमें कोई चाइल्ड टैग नहीं होता, इसलिए यह अपने साइज़ का फ़ैसला खुद लेता है और इसकी जानकारीColumn
को देता है.
- दूसरा
Column
, बच्चे की मेज़रमेंट का इस्तेमाल करके अपना साइज़ तय करता है. यह चाइल्ड की ज़्यादा से ज़्यादा चौड़ाई और उसके चाइल्ड की ऊंचाई के योग का इस्तेमाल करता है.Column
अपने चाइल्ड विजेट को खुद के हिसाब से रखता है. साथ ही, उन्हें एक-दूसरे के नीचे वर्टिकल तौर पर रखता है.Row
, बच्चे की मेज़रमेंट का इस्तेमाल करके अपना साइज़ तय करता है. यह सबसे बड़े चाइल्ड एलिमेंट की ऊंचाई और उसके चाइल्ड एलिमेंट की चौड़ाई के योग का इस्तेमाल करता है. इसके बाद, यह अपने बच्चों को जगह देता है.
ध्यान दें कि हर नोड पर सिर्फ़ एक बार विज़िट किया गया था. Compose रनटाइम को सभी नोड को मेज़र करने और उन्हें प्लेस करने के लिए, यूज़र इंटरफ़ेस (यूआई) ट्री में सिर्फ़ एक बार पास करना पड़ता है. इससे परफ़ॉर्मेंस बेहतर होती है. जब ट्री में नोड की संख्या बढ़ती है, तो उसमें ट्रैवर्स करने में लगने वाला समय, लीनियर तरीके से बढ़ता है. इसके उलट, अगर हर नोड को कई बार विज़िट किया गया था, तो ट्रैवर्सल का समय बहुत ज़्यादा बढ़ जाता है.
ड्रॉइंग
ड्रॉइंग फ़ेज़ में, ट्री को फिर से ऊपर से नीचे तक ट्रैवर्स किया जाता है. साथ ही, हर नोड, स्क्रीन पर अपने-आप ड्रॉ होता है.
पांचवीं इमेज. ड्रॉइंग फ़ेज़ में, स्क्रीन पर पिक्सल बनाए जाते हैं.
पिछले उदाहरण का इस्तेमाल करके, ट्री कॉन्टेंट को इस तरह से बनाया गया है:
Row
, बैकग्राउंड का रंग जैसे कॉन्टेंट को दिखाता है.Image
अपने-आप बन जाता है.Column
अपने-आप बन जाता है.- पहला और दूसरा
Text
, खुद को क्रमशः ड्रॉ करते हैं.
छठी इमेज. यूज़र इंटरफ़ेस (यूआई) ट्री और उसका ड्रॉ किया गया वर्शन.
स्टेटस पढ़ना
जब आपने पहले बताए गए किसी चरण के दौरान, snapshot state
का value
पढ़ा, तो Compose अपने-आप ट्रैक करता है कि value
पढ़ते समय वह क्या कर रहा था. इस ट्रैकिंग की मदद से, Compose में स्टेटस के value
में बदलाव होने पर, रीडर को फिर से चलाया जा सकता है. साथ ही, यह Compose में स्टेटस को मॉनिटर करने की सुविधा का आधार है.
आम तौर पर, mutableStateOf()
का इस्तेमाल करके स्टेटस बनाया जाता है. इसके बाद, इसे दो में से किसी एक तरीके से ऐक्सेस किया जाता है: सीधे तौर पर value
प्रॉपर्टी को ऐक्सेस करके या Kotlin प्रॉपर्टी डेलिगेट का इस्तेमाल करके. इनके बारे में ज़्यादा जानने के लिए, कंपोज़ेबल में मौजूद स्टेटस लेख पढ़ें. इस गाइड के लिए, "स्टेटस पढ़ना" का मतलब, ऐक्सेस करने के उन मिलते-जुलते तरीकों में से किसी एक से है.
// State read without property delegate. val paddingState: MutableState<Dp> = remember { mutableStateOf(8.dp) } Text( text = "Hello", modifier = Modifier.padding(paddingState.value) )
// State read with property delegate. var padding: Dp by remember { mutableStateOf(8.dp) } Text( text = "Hello", modifier = Modifier.padding(padding) )
प्रॉपर्टी डेलिगेट के तहत, "गेटर" और "सेटर" फ़ंक्शन का इस्तेमाल, स्टेट के value
को ऐक्सेस और अपडेट करने के लिए किया जाता है. ये getter और
setter फ़ंक्शन सिर्फ़ तब ट्रिगर होते हैं, जब प्रॉपर्टी को वैल्यू के तौर पर रेफ़र किया जाता है,
न कि इसे बनाने के दौरान. इसलिए, पहले बताए गए दोनों तरीके एक जैसे हैं.
कोड का हर वह ब्लॉक जिसे पढ़ने की स्थिति में बदलाव होने पर फिर से चलाया जा सकता है, वह फिर से शुरू करने का स्कोप होता है. Compose, स्टेटस value
में होने वाले बदलावों और अलग-अलग चरणों में स्कोप को फिर से शुरू करने का ट्रैक रखता है.
अलग-अलग चरणों में स्टेटस पढ़ना
जैसा कि पहले बताया गया है, Compose में तीन मुख्य चरण होते हैं. साथ ही, Compose यह ट्रैक करता है कि इनमें से हर चरण में कौनसी स्थिति पढ़ी गई है. इससे Compose, सिर्फ़ उन फ़ेज़ को सूचना दे पाता है जिन्हें आपके यूज़र इंटरफ़ेस (यूआई) के उन सभी एलिमेंट के लिए काम करना है जिन पर असर पड़ा है.
नीचे दिए गए सेक्शन में हर चरण के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि किसी स्टेट वैल्यू को पढ़ने पर क्या होता है.
पहला चरण: कंपोज़िशन
@Composable
फ़ंक्शन या लैम्ब्डा ब्लॉक में स्टेटस पढ़ने से, कॉम्पोज़िशन और संभावित तौर पर बाद के चरणों पर असर पड़ता है. जब स्टेटस का value
बदलता है, तो फिर से कंपोज़ करने वाला टूल उन सभी कॉम्पोज़ेबल फ़ंक्शन को फिर से चलाने के लिए शेड्यूल करता है जो उस स्टेटस का value
पढ़ते हैं. ध्यान दें कि अगर इनपुट में कोई बदलाव नहीं हुआ है, तो रनटाइम कुछ या सभी कंपोज़ेबल फ़ंक्शन को स्किप कर सकता है. ज़्यादा जानकारी के लिए, अगर इनपुट में बदलाव नहीं हुआ है, तो स्किप करना लेख पढ़ें.
कॉम्पोज़िशन के नतीजे के आधार पर, Compose यूज़र इंटरफ़ेस (यूआई) लेआउट और ड्रॉइंग के चरण चलाता है. अगर कॉन्टेंट एक जैसा रहता है और साइज़ और लेआउट में कोई बदलाव नहीं होता है, तो हो सकता है कि यह इन चरणों को छोड़ दे.
var padding by remember { mutableStateOf(8.dp) } Text( text = "Hello", // The `padding` state is read in the composition phase // when the modifier is constructed. // Changes in `padding` will invoke recomposition. modifier = Modifier.padding(padding) )
दूसरा चरण: लेआउट
लेआउट फ़ेज़ में दो चरण होते हैं: मेज़रमेंट और प्लेसमेंट. मेज़रमेंट चरण, Layout
कॉम्पोज़ेबल, LayoutModifier
इंटरफ़ेस के MeasureScope.measure
तरीके वगैरह में पास किए गए मेज़र लेम्ब्डा को चलाता है.
प्लेसमेंट चरण, layout
फ़ंक्शन का प्लेसमेंट ब्लॉक, Modifier.offset { … }
का लैम्ब्डा ब्लॉक, और मिलते-जुलते फ़ंक्शन चलाता है.
इनमें से हर चरण के दौरान स्टेटस पढ़ने से लेआउट और ड्रॉइंग फ़ेज़ पर असर पड़ता है. जब स्टेटस का value
बदलता है, तो Compose यूज़र इंटरफ़ेस (यूआई), लेआउट फ़ेज़ को शेड्यूल करता है. साइज़ या पोज़िशन में बदलाव होने पर, यह ड्रॉइंग फ़ेज़ भी चलाता है.
var offsetX by remember { mutableStateOf(8.dp) } Text( text = "Hello", modifier = Modifier.offset { // The `offsetX` state is read in the placement step // of the layout phase when the offset is calculated. // Changes in `offsetX` restart the layout. IntOffset(offsetX.roundToPx(), 0) } )
तीसरा चरण: ड्रॉइंग
ड्रॉइंग कोड के दौरान स्टेटस पढ़ने से, ड्रॉइंग फ़ेज़ पर असर पड़ता है. आम तौर पर, Canvas()
, Modifier.drawBehind
, और Modifier.drawWithContent
जैसे नाम इस्तेमाल किए जाते हैं. जब राज्य का value
बदलता है, तो Compose यूज़र इंटरफ़ेस (यूआई) सिर्फ़ ड्रॉ फ़ेज़ चलाता है.
var color by remember { mutableStateOf(Color.Red) } Canvas(modifier = modifier) { // The `color` state is read in the drawing phase // when the canvas is rendered. // Changes in `color` restart the drawing. drawRect(color) }
Optimize की स्टेटस रीड
Compose, स्थानीय तौर पर स्टेटस रीड ट्रैकिंग करता है. इसलिए, हर स्टेटस को सही फ़ेज़ में पढ़कर, किए जाने वाले काम की संख्या कम की जा सकती है.
नीचे दिया गया उदाहरण देखें. इस उदाहरण में एक Image()
है, जो अपने फ़ाइनल लेआउट की पोज़िशन को ऑफ़सेट करने के लिए, ऑफ़सेट मॉडिफ़ायर का इस्तेमाल करता है. इसकी वजह से, उपयोगकर्ता के स्क्रोल करने पर पैरलॅक्स इफ़ेक्ट दिखता है.
Box { val listState = rememberLazyListState() Image( // ... // Non-optimal implementation! Modifier.offset( with(LocalDensity.current) { // State read of firstVisibleItemScrollOffset in composition (listState.firstVisibleItemScrollOffset / 2).toDp() } ) ) LazyColumn(state = listState) { // ... } }
यह कोड काम करता है, लेकिन इससे परफ़ॉर्मेंस में गिरावट आती है. जैसा कि लिखा गया है, कोड firstVisibleItemScrollOffset
स्टेटस का value
पढ़ता है और उसे Modifier.offset(offset: Dp)
फ़ंक्शन को पास करता है. जब उपयोगकर्ता स्क्रोल करता है, तो firstVisibleItemScrollOffset
का value
बदल जाएगा. जैसा कि आपने जाना है कि Compose, किसी भी स्टेटस को पढ़ने की प्रोसेस को ट्रैक करता है, ताकि वह पढ़ने के कोड को फिर से शुरू कर सके. इस उदाहरण में, Box
का कॉन्टेंट पढ़ने का कोड.
यह कंपोज़िशन फ़ेज़ में किसी स्टेटस को पढ़ने का उदाहरण है. यह ज़रूरी नहीं है कि यह कोई बुरी बात हो. असल में, यह फिर से कॉम्पोज़ करने का आधार है. इससे डेटा में हुए बदलावों की वजह से नया यूज़र इंटरफ़ेस (यूआई) जनरेट होता है.
अहम जानकारी: यह उदाहरण सही नहीं है, क्योंकि हर स्क्रोल इवेंट की वजह से, पूरे कॉम्पोज़ेबल कॉन्टेंट का फिर से आकलन किया जाता है, उसे मेज़र किया जाता है, उसे लेआउट किया जाता है, और आखिर में उसे ड्रॉ किया जाता है. हर बार स्क्रोल करने पर, लिखने का फ़ेज़ ट्रिगर होता है. भले ही, दिखाया गया कॉन्टेंट न बदला हो, सिर्फ़ उसकी पोज़िशन बदली हो. सिर्फ़ लेआउट फ़ेज़ को फिर से ट्रिगर करने के लिए, स्टेटस रीड को ऑप्टिमाइज़ किया जा सकता है.
lambda फ़ंक्शन का इस्तेमाल करके ऑफ़सेट
ऑफ़सेट मॉडिफ़ायर का एक और वर्शन उपलब्ध है:
Modifier.offset(offset: Density.() -> IntOffset)
.
यह वर्शन, lambda पैरामीटर लेता है. इसमें, lambda ब्लॉक से नतीजा के तौर पर ऑफ़सेट मिलता है. इसका इस्तेमाल करने के लिए, कोड अपडेट करें:
Box { val listState = rememberLazyListState() Image( // ... Modifier.offset { // State read of firstVisibleItemScrollOffset in Layout IntOffset(x = 0, y = listState.firstVisibleItemScrollOffset / 2) } ) LazyColumn(state = listState) { // ... } }
तो यह ज़्यादा बेहतर परफ़ॉर्म क्यों करता है? मॉडिफ़ायर को दिया गया आपका लैम्ब्डा ब्लॉक, लेआउट फ़ेज़ के दौरान (खास तौर पर, लेआउट फ़ेज़ के प्लेसमेंट चरण के दौरान) शुरू किया जाता है. इसका मतलब है कि कॉम्पोज़िशन के दौरान firstVisibleItemScrollOffset
स्टेटस नहीं पढ़ा जाता. Compose, स्टेटस पढ़ने के दौरान ट्रैक करता है. इसलिए, इस बदलाव का मतलब है कि अगर firstVisibleItemScrollOffset
का value
बदलता है, तो Compose को सिर्फ़ लेआउट और ड्रॉइंग के चरणों को फिर से शुरू करना होगा.
हालांकि, कॉम्पोज़िशन के फ़ेज़ में स्टेटस पढ़ना ज़रूरी होता है. इसके बावजूद, कुछ मामलों में स्टेटस में हुए बदलावों को फ़िल्टर करके, फिर से कॉम्पोनेंट बनाने की संख्या को कम किया जा सकता है. इस बारे में ज़्यादा जानकारी के लिए,
derivedStateOf
: एक या एक से ज़्यादा स्टेटस ऑब्जेक्ट को किसी दूसरी स्थिति में बदलना लेख पढ़ें.
फिर से कॉम्पोज़ करने वाला लूप (साइकल के फ़ेज़ पर निर्भरता)
इस गाइड में पहले बताया गया था कि Compose के फ़ेज़ हमेशा एक ही क्रम में शुरू होते हैं. साथ ही, एक ही फ़्रेम में पीछे जाने का कोई तरीका नहीं है. हालांकि, इससे ऐप्लिकेशन को अलग-अलग फ़्रेम में कॉम्पोज़िशन लूप में जाने से नहीं रोका जा सकता. इस उदाहरण से समझें:
Box { var imageHeightPx by remember { mutableStateOf(0) } Image( painter = painterResource(R.drawable.rectangle), contentDescription = "I'm above the text", modifier = Modifier .fillMaxWidth() .onSizeChanged { size -> // Don't do this imageHeightPx = size.height } ) Text( text = "I'm below the image", modifier = Modifier.padding( top = with(LocalDensity.current) { imageHeightPx.toDp() } ) ) }
इस उदाहरण में, वर्टिकल कॉलम का इस्तेमाल किया गया है. इसमें सबसे ऊपर इमेज है और उसके नीचे टेक्स्ट है. यह इमेज का रिज़ॉल्यूशन पाने के लिए Modifier.onSizeChanged()
का इस्तेमाल करता है. इसके बाद, टेक्स्ट को नीचे ले जाने के लिए Modifier.padding()
का इस्तेमाल करता है.
Px
से Dp
पर वापस जाने वाले अस्वाभाविक कन्वर्ज़न से पहले ही पता चलता है कि कोड में कोई समस्या है.
इस उदाहरण में समस्या यह है कि कोड एक ही फ़्रेम में "फ़ाइनल" लेआउट पर नहीं पहुंचता. यह कोड कई फ़्रेम पर निर्भर करता है, जो ग़ैर-ज़रूरी काम करता है. इसकी वजह से, उपयोगकर्ता के लिए यूज़र इंटरफ़ेस (यूआई) स्क्रीन पर इधर-उधर कूदता रहता है.
पहले फ़्रेम का कंपोज़िशन
पहले फ़्रेम के कॉम्पोज़िशन फ़ेज़ के दौरान, imageHeightPx
शुरू में
0
होता है. इसलिए, कोड में Modifier.padding(top = 0)
वाला टेक्स्ट दिखता है.
इसके बाद, लेआउट का दूसरा चरण onSizeChanged
मॉडिफ़ायर के कॉलबैक को ट्रिगर करता है. इससे imageHeightPx
, इमेज की असल ऊंचाई पर अपडेट हो जाता है. कॉम्पोज़ करने के बाद, अगले फ़्रेम के लिए फिर से कॉम्पोज़ करने का शेड्यूल सेट किया जाता है. हालांकि, मौजूदा खींचने के चरण के दौरान, टेक्स्ट 0
के पैडिंग के साथ रेंडर होता है, क्योंकि अपडेट की गई imageHeightPx
वैल्यू अब तक नहीं दिखी है.
दूसरे फ़्रेम का कंपोज़िशन
imageHeightPx
की वैल्यू में हुए बदलाव की वजह से, Compose दूसरा फ़्रेम शुरू करता है. इस फ़्रेम के कॉम्पोज़िशन फ़ेज़ में, Box
कॉन्टेंट ब्लॉक में स्टेटस पढ़ा जाता है. टेक्स्ट में अब पैडिंग दी गई है, जो इमेज की ऊंचाई से पूरी तरह मेल खाती है. लेआउट फ़ेज़ के दौरान, imageHeightPx
को फिर से सेट किया जाता है. हालांकि, वैल्यू में कोई बदलाव न होने की वजह से, फिर से कॉम्पोज़ करने का कोई शेड्यूल नहीं किया जाता.
यह उदाहरण बनावटी लग सकता है, लेकिन इस सामान्य पैटर्न से सावधान रहें:
Modifier.onSizeChanged()
,onGloballyPositioned()
या लेआउट के कुछ अन्य ऑपरेशन- किसी स्टेटस को अपडेट करना
- उस स्थिति का इस्तेमाल, लेआउट मॉडिफ़ायर (
padding()
,height()
या मिलते-जुलते) के इनपुट के तौर पर करें - दोहराए जाने की संभावना
पिछले सैंपल को ठीक करने के लिए, सही लेआउट प्राइमिटिव का इस्तेमाल करें. ऊपर दिए गए उदाहरण को Column()
के साथ लागू किया जा सकता है. हालांकि, आपके पास ज़्यादा जटिल उदाहरण हो सकता है, जिसके लिए कस्टम लेआउट लिखना ज़रूरी होगा. ज़्यादा जानकारी के लिए, कस्टम लेआउट गाइड देखें
यहां सामान्य सिद्धांत यह है कि कई यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए एक ही सोर्स होना चाहिए. इन एलिमेंट को एक-दूसरे के हिसाब से मेज़र और प्लेस किया जाना चाहिए. सही लेआउट प्रिमिटिव का इस्तेमाल करने या कस्टम लेआउट बनाने का मतलब है कि कम से कम शेयर किया गया पैरंट, सच्चाई के सोर्स के तौर पर काम करता है. यह कई एलिमेंट के बीच संबंध को मैनेज कर सकता है. डाइनैमिक स्टेटस की सुविधा जोड़ने से, यह सिद्धांत नहीं चलता.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- स्टेट और Jetpack Compose
- सूची और ग्रिड
- Jetpack Compose के लिए Kotlin