Compose का एक नियम यह भी है कि आपको अपने बच्चों का आकलन सिर्फ़ एक बार करना चाहिए; बच्चों को दो बार मापने से रनटाइम अपवाद मिलता है. हालांकि, कई बार ऐसा भी होता है भी नहीं है.
Intrinsics की मदद से, बच्चों को मेज़र करने से पहले ही उनसे क्वेरी करने की सुविधा मिलती है.
किसी कंपोज़ेबल में intrinsicWidth
या intrinsicHeight
मांगा जा सकता है:
(min|max)IntrinsicWidth
: इस चौड़ाई को देखते हुए, कम से कम/ज़्यादा से ज़्यादा कितना हो सकता है क्या आप अपने कॉन्टेंट को सही तरह से पेंट कर सकते हैं?(min|max)IntrinsicHeight
: इस ऊंचाई को देखते हुए, कम से कम/ज़्यादा से ज़्यादा कितना हो सकता है की ऊंचाई के हिसाब से अपने कॉन्टेंट को सही ढंग से पेंट करने में मदद कर सकते हैं?
उदाहरण के लिए, अगर किसी ऐसे Text
का minIntrinsicHeight
पूछा जाता है जिसमें अनलिमिटेड height
हों, तो यह Text
का height
वैसा ही दिखाएगा जैसे टेक्स्ट को एक पंक्ति में लिखा गया हो.
Intrinsics का इस्तेमाल
मान लें कि हम एक ऐसा कंपोज़ेबल बनाना चाहते हैं जो स्क्रीन को इस तरह से डिवाइडर से अलग करें:
हम यह कैसे कर सकते हैं? हमारे पास दो Text
के साथ एक Row
हो सकता है, जो इस तरह बड़ा होता है
स्क्रीन के बीच में एक Divider
. हम चाहते हैं कि Divider
सबसे ऊंचा Text
और पतला (width = 1.dp
) लंबा.
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) HorizontalDivider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
अगर हम इसकी झलक देखते हैं, तो हमें पता चलता है कि Divider
पूरी स्क्रीन पर बड़ा हो जाता है और
हम यह नहीं चाहते:
ऐसा इसलिए होता है, क्योंकि Row
हर बच्चे की ऊंचाई को अलग-अलग मेज़र करता है. साथ ही, Text
की सीमा तय करने के लिए, Text
की ऊंचाई का इस्तेमाल नहीं किया जा सकता. हम चाहते हैं कि Divider
, उपलब्ध जगह को तय की गई ऊंचाई के हिसाब से भर दे. इसके लिए, हम
height(IntrinsicSize.Min)
मॉडिफ़ायर का इस्तेमाल कर सकते हैं .
height(IntrinsicSize.Min)
अपने बच्चों को उनकी कम से कम प्राकृतिक ऊंचाई के बराबर ऊंचा करने के लिए मजबूर करता है. बार-बार होने की वजह से, यह Row
और इसके
बच्चे minIntrinsicHeight
.
इसे अपने कोड पर लागू करने से, यह उम्मीद के मुताबिक काम करेगा:
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier.height(IntrinsicSize.Min)) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) HorizontalDivider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } } // @Preview @Composable fun TwoTextsPreview() { MaterialTheme { Surface { TwoTexts(text1 = "Hi", text2 = "there") } } }
झलक के साथ:
Row
कॉम्पोज़ेबल का minIntrinsicHeight
, उसके बच्चों का ज़्यादा से ज़्यादा
minIntrinsicHeight
होगा. Divider
एलिमेंट का minIntrinsicHeight
0 होता है, क्योंकि कोई पाबंदी न होने पर यह जगह नहीं लेता. Text
minIntrinsicHeight
, उस टेक्स्ट का होगा जिसे कोई खास width
दिया गया है. इसलिए, Row
एलिमेंट का height
कंस्ट्रेंट
Text
में से minIntrinsicHeight
. इसके बाद, Divider
अपने height
को Row
की तय की गई height
सीमा तक बढ़ा देगा.
आपके कस्टम लेआउट में इनट्रिन्सिक
कस्टम Layout
या layout
मॉडिफ़ायर बनाते समय, अनुमान के आधार पर इनट्रिन्सिक मेज़रमेंट अपने-आप कैलकुलेट हो जाते हैं. इसलिए,
ऐसा हो सकता है कि सभी लेआउट के लिए कैलकुलेशन सही न हों. ये एपीआई, इन डिफ़ॉल्ट वैल्यू को बदलने के विकल्प देते हैं.
अपने पसंद के मुताबिक बनाए गए Layout
के अंदरूनी माप बताने के लिए,
minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
को बदलें
और maxIntrinsicHeight
MeasurePolicy
उसे बनाते समय उसका इस्तेमाल किया जा सकता है.
@Composable fun MyCustomComposable( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( content = content, modifier = modifier, measurePolicy = object : MeasurePolicy { override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurables: List<IntrinsicMeasurable>, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. } ) }
अपना कस्टम layout
मॉडिफ़ायर बनाते समय, LayoutModifier
इंटरफ़ेस में मिलते-जुलते तरीकों को बदलें.
fun Modifier.myCustomModifier(/* ... */) = this then object : LayoutModifier { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurable: IntrinsicMeasurable, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. }
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- कस्टम लेआउट {:#custom-layouts }
- Jetpack Compose में अलाइनमेंट लाइनें
- Jetpack Compose के चरण