Compose का एक नियम यह है कि आपको अपने बच्चों को सिर्फ़ एक बार मेज़र करना चाहिए; बच्चों को दो बार मेज़र करने पर, रनटाइम अपवाद दिखता है. हालांकि, कई बार आपको अपने बच्चों के बारे में कुछ जानकारी की ज़रूरत होती है, ताकि उनकी लंबाई मापी जा सके.
इंट्रिंसिक की मदद से, बच्चों की परफ़ॉर्मेंस का आकलन करने से पहले उनसे सवाल पूछे जा सकते हैं.
किसी कंपोज़ेबल के लिए, IntrinsicSize.Min
या IntrinsicSize.Max
के बारे में पूछा जा सकता है:
Modifier.width(IntrinsicSize.Min)
- अपने कॉन्टेंट को सही तरीके से दिखाने के लिए, आपको कम से कम कितनी चौड़ाई की ज़रूरत है?Modifier.width(IntrinsicSize.Max)
- कॉन्टेंट को सही तरीके से दिखाने के लिए, आपको ज़्यादा से ज़्यादा कितनी चौड़ाई चाहिए?Modifier.height(IntrinsicSize.Min)
- कॉन्टेंट को सही तरीके से दिखाने के लिए, कम से कम कितनी ऊंचाई की ज़रूरत होती है?Modifier.height(IntrinsicSize.Max)
- कॉन्टेंट को सही तरीके से दिखाने के लिए, आपको ज़्यादा से ज़्यादा कितनी ऊंचाई की ज़रूरत है?
उदाहरण के लिए, अगर कस्टम लेआउट में width
की अनंत सीमाओं वाले Text
के minIntrinsicHeight
का अनुरोध किया जाता है, तो यह Text
के height
को एक लाइन में टेक्स्ट के साथ दिखाएगा.
इंट्रिंसिक फ़ंक्शन का इस्तेमाल
मान लें कि हमें एक ऐसा कंपोज़ेबल बनाना है जो स्क्रीन पर दो टेक्स्ट दिखाता है. दोनों टेक्स्ट के बीच में इस तरह का डिवाइडर होता है:
हम ऐसा कैसे कर सकते हैं? हमारे पास एक Row
हो सकता है, जिसमें दो Text
हों. ये 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 ) VerticalDivider( 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
की ऊंचाई का इस्तेमाल, 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 ) VerticalDivider( 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
, Row
की दी गई height
की सीमा के हिसाब से, अपनी 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 के फ़ेज़