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 कंपोज़ेबल होने चाहिए, जो उपलब्ध जगह को भरें. साथ ही, बीच में एक 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 की ऊंचाई इस तरह तय की जाती है:
Rowकंपोज़ेबल काminIntrinsicHeight, इसके चाइल्ड कंपोज़ेबल का ज़्यादा से ज़्यादाminIntrinsicHeightहोता है.Dividerएलिमेंट काminIntrinsicHeight0 है, क्योंकि अगर कोई शर्त नहीं दी गई है, तो यह जगह नहीं लेता.TextminIntrinsicHeight, किसी खास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 के फ़ेज़