Compose का एक नियम यह है कि आपको अपने बच्चों को सिर्फ़ एक बार मेज़र करना चाहिए. बच्चों को दो बार मेज़र करने पर, रनटाइम एक्सप्शन दिखता है. हालांकि, कभी-कभी ऐसा होता है कि बच्चों की परफ़ॉर्मेंस का आकलन करने से पहले, आपको उनके बारे में कुछ जानकारी चाहिए.
Intrinsics की मदद से, बच्चों की परफ़ॉर्मेंस का आकलन करने से पहले ही उनके बारे में जानकारी हासिल की जा सकती है.
किसी कॉम्पोज़ेबल के लिए, intrinsicWidth
या intrinsicHeight
का अनुरोध किया जा सकता है:
(min|max)IntrinsicWidth
: इस चौड़ाई के हिसाब से, कॉन्टेंट को सही तरीके से दिखाने के लिए, कम से कम/ज़्यादा से ज़्यादा कितनी चौड़ाई की ज़रूरत होगी?(min|max)IntrinsicHeight
: इस ऊंचाई के हिसाब से, कॉन्टेंट को सही तरीके से पेंट करने के लिए, कम से कम/ज़्यादा से ज़्यादा कितनी ऊंचाई की ज़रूरत होगी?
उदाहरण के लिए, अगर किसी ऐसे Text
का minIntrinsicHeight
पूछा जाता है जिसमें अनलिमिटेड height
हों, तो यह Text
का height
वैसा ही दिखाएगा जैसे टेक्स्ट को एक पंक्ति में लिखा गया हो.
Intrinsics का इस्तेमाल
मान लें कि हमें एक ऐसा कॉम्पोज़ेबल बनाना है जो स्क्रीन पर दो टेक्स्ट दिखाता हो और उन्हें इस तरह से अलग करता हो:
हम ऐसा कैसे कर सकते हैं? हमारे पास Row
में दो Text
हो सकते हैं, जो ज़्यादा से ज़्यादा तक फैल सकते हैं और बीच में एक 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
हम चाहते हैं कि 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
के इंट्रिन्सिक मेज़रमेंट की जानकारी देने के लिए,
MeasurePolicy
इंटरफ़ेस बनाते समय, minIntrinsicWidth
, minIntrinsicHeight
, maxIntrinsicWidth
, और maxIntrinsicHeight
को बदलें.
@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 के चरण