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 को दिखाता है. इसमें टेक्स्ट को एक ही लाइन में लिखा जाता है.
इंट्रिंसिक फ़ंक्शन का इस्तेमाल
ऐसा कंपोज़ेबल बनाया जा सकता है जो स्क्रीन पर दो टेक्स्ट दिखाता है. इन दोनों टेक्स्ट को एक डिवाइडर से अलग किया जाता है:
इसके लिए, दो 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 ) 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,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 के फ़ेज़