कस्टम लेआउट

Compose में, यूज़र इंटरफ़ेस (यूआई) एलिमेंट को कंपोज़ेबल फ़ंक्शन के ज़रिए दिखाया जाता है. इन एलिमेंट से शुरू किए जाने पर यूज़र इंटरफ़ेस (यूआई) का वह हिस्सा, जिसे शुरू करने के बाद उसे यूज़र इंटरफ़ेस ट्री में जोड़ दिया जाता है, जो स्क्रीन. हर यूज़र इंटरफ़ेस (यूआई) एलिमेंट में एक पैरंट और कई चाइल्ड हो सकते हैं. हर एलिमेंट अपने पैरंट के अंदर मौजूद है, जो (x, y) पोज़िशन के रूप में बताया गया है और एक साइज़, जिसे width और height के तौर पर बताया जाता है.

माता-पिता अपने चाइल्ड एलिमेंट के लिए सीमाएं तय करते हैं. किसी एलिमेंट को इन कंस्ट्रेंट के अंदर अपना साइज़ तय करें. पाबंदियों की वजह से कम से कम और एलिमेंट के ज़्यादा से ज़्यादा width और height. अगर किसी एलिमेंट में चाइल्ड एलिमेंट हैं, तो वह हर बच्चे की गतिविधि को माप सकता है, ताकि उसका साइज़ तय करने में मदद मिल सके. जब कोई एलिमेंट तय करता है और अपने साइज़ की रिपोर्ट देता है, तो वह यह तय कर सकता है कि अपने बच्चे को किस तरह जैसा कि अनुभव के आधार पर बनाया गया है) लेआउट.

यूज़र इंटरफ़ेस ट्री में हर नोड को तीन चरणों वाली प्रोसेस में रखा जाता है. हर नोड में:

  1. किसी चाइल्ड साइट को मापें
  2. उसका साइज़ खुद तय करें
  3. इसके चिल्ड्रेन प्लेस करें

नोड लेआउट के तीन चरण: बच्चों को मापना, साइज़ तय करना, और बच्चों को जगह देना

स्कोप के इस्तेमाल से यह तय होता है कि अपने बच्चों को कब मेज़र और रखा जा सकता है. लेआउट को सिर्फ़ मेज़रमेंट और लेआउट पास करने के दौरान ही मेज़र किया जा सकता है. और बच्चे को सिर्फ़ लेआउट पास करने के दौरान ही रखा जा सकता है (और इसके बाद ही मेज़र किया गया है). 'लिखें' स्कोप की वजह से, जैसे कि MeasureScope और PlacementScope, इसे कंपाइल करने के दौरान लागू किया जाता है.

लेआउट मॉडिफ़ायर का इस्तेमाल करना

किसी एलिमेंट को मेज़र करने और रखने का तरीका बदलने के लिए, layout मॉडिफ़ायर का इस्तेमाल किया जा सकता है बाहर. Layout एक Lambda फ़ंक्शन है; इसके पैरामीटर में ऐसा एलिमेंट शामिल है जिसे मेज़र किया जा सकता है, measurable के रूप में पास किया गया है और उस कंपोज़ेबल के इनकमिंग कंस्ट्रेंट, constraints. कस्टम लेआउट मॉडिफ़ायर, ऐसा दिख सकता है:

fun Modifier.customLayoutModifier() =
    layout { measurable, constraints ->
        // ...
    }

स्क्रीन पर Text दिखाएं. साथ ही, इसके सबसे ऊपर के हिस्से के बीच की दूरी को कंट्रोल करें टेक्स्ट की पहली लाइन की बेसलाइन शामिल है. यही वजह है कि paddingFromBaseline मॉडिफ़ायर काम करता है, इसलिए हम यहां इसे उदाहरण के तौर पर लागू कर रहे हैं. ऐसा करने के लिए, layout मॉडिफ़ायर का इस्तेमाल करके, कंपोज़ेबल को मैन्युअल तरीके से स्क्रीन. यहां बताया गया है कि Text टॉप पैडिंग 24.dp को कैसे सेट किया जाता है:

यह सामान्य यूज़र इंटरफ़ेस (यूआई) पैडिंग के बीच का अंतर दिखाता है. यह एलिमेंट और टेक्स्ट पैडिंग के बीच स्पेस सेट करता है, जो स्पेस को एक बेसलाइन से अगली पर सेट करता है

वह स्पेस बनाने के लिए कोड यहां दिया गया है:

fun Modifier.firstBaselineToTop(
    firstBaselineToTop: Dp
) = layout { measurable, constraints ->
    // Measure the composable
    val placeable = measurable.measure(constraints)

    // Check the composable has a first baseline
    check(placeable[FirstBaseline] != AlignmentLine.Unspecified)
    val firstBaseline = placeable[FirstBaseline]

    // Height of the composable with padding - first baseline
    val placeableY = firstBaselineToTop.roundToPx() - firstBaseline
    val height = placeable.height + placeableY
    layout(placeable.width, height) {
        // Where the composable gets placed
        placeable.placeRelative(0, placeableY)
    }
}

यहां बताया गया है कि उस कोड में क्या हो रहा है:

  1. measurable Lambda पैरामीटर में, Text को मेज़र करने के लिए, इस तरीके का इस्तेमाल किया जाता है: measurable.measure(constraints) को कॉल करके मेज़र किए जा सकने वाले पैरामीटर चुने जा सकते हैं.
  2. layout(width, height) पर कॉल करके, कंपोज़ेबल का साइज़ तय किया जा सकता है तरीका, जिससे रैप किए गए एलिमेंट को रखने के लिए इस्तेमाल होने वाला लैम्डा भी मिलता है. तय सीमा में इस मामले में, यह आखिरी बेसलाइन और जोड़ी गई टॉप पैडिंग के बीच की ऊंचाई है.
  3. रैप किए गए एलिमेंट को स्क्रीन पर दिखाने के लिए, placeable.place(x, y). अगर रैप किए गए एलिमेंट नहीं रखे गए हैं, तो वे दृश्य. y पोज़िशन टॉप पैडिंग के हिसाब से होती है - इसकी पोज़िशन टेक्स्ट की पहली बेसलाइन शामिल है.

यह पुष्टि करने के लिए कि यह उम्मीद के मुताबिक काम करता है, Text पर इस मॉडिफ़ायर का इस्तेमाल करें:

@Preview
@Composable
fun TextWithPaddingToBaselinePreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.firstBaselineToTop(32.dp))
    }
}

@Preview
@Composable
fun TextWithNormalPaddingPreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.padding(top = 32.dp))
    }
}

टेक्स्ट एलिमेंट की एक से ज़्यादा झलक; एक एलिमेंट के बीच सामान्य पैडिंग (जगह) दिखाता है, वहीं दूसरा एलिमेंट, एक बेसलाइन से दूसरी बेसलाइन तक पैडिंग (जगह) दिखाता है

पसंद के मुताबिक लेआउट बनाना

layout मॉडिफ़ायर सिर्फ़ कॉल करने के कंपोज़ेबल को बदलता है. लेआउट और मापने के लिए एक से ज़्यादा कंपोज़ेबल में शामिल किया गया है, तो इसके बजाय Layout कंपोज़ेबल का इस्तेमाल करें. यह कंपोज़ेबल की मदद से, बच्चों को मैन्युअल तौर पर मेज़र और आउट किया जा सकता है. सभी हाई-लेवल लेआउट जैसे, Column और Row, Layout कंपोज़ेबल के साथ बनाए गए हैं.

चलिए, Column का सबसे बेसिक वर्शन बनाते हैं. ज़्यादातर कस्टम लेआउट इसका पालन करते हैं पैटर्न:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // measure and position children given constraints logic here
        // ...
    }
}

layout मॉडिफ़ायर की तरह ही, measurables उन बच्चों की सूची है जिनमें को मापा जाना चाहिए और constraints पैरंट की पाबंदियां हैं. पहले की तरह ही, MyBasicColumn को इस तरह लागू किया जा सकता है शामिल करें:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // Don't constrain child views further, measure them with given constraints
        // List of measured children
        val placeables = measurables.map { measurable ->
            // Measure each children
            measurable.measure(constraints)
        }

        // Set the size of the layout as big as it can
        layout(constraints.maxWidth, constraints.maxHeight) {
            // Track the y co-ord we have placed children up to
            var yPosition = 0

            // Place children in the parent layout
            placeables.forEach { placeable ->
                // Position item on the screen
                placeable.placeRelative(x = 0, y = yPosition)

                // Record the y co-ord placed up to
                yPosition += placeable.height
            }
        }
    }
}

चाइल्ड कंपोज़ेबल, Layout की शर्तों के तहत सीमित होते हैं. minHeight कंस्ट्रेंट), और इन्हें yPosition पिछले कंपोज़ेबल.

यहां बताया गया है कि कस्टम कंपोज़ेबल का इस्तेमाल कैसे किया जाएगा:

@Composable
fun CallingComposable(modifier: Modifier = Modifier) {
    MyBasicColumn(modifier.padding(8.dp)) {
        Text("MyBasicColumn")
        Text("places items")
        Text("vertically.")
        Text("We've done it by hand!")
    }
}

कॉलम में कई टेक्स्ट एलिमेंट को अगले के ऊपर रखा गया है.

लेआउट की दिशा

कंपोज़ेबल के लेआउट की दिशा बदलने के लिए, LocalLayoutDirection कंपोज़िशन स्थानीय.

अगर कंपोज़ेबल को स्क्रीन पर मैन्युअल तरीके से जोड़ा जा रहा है, तो LayoutDirection यह layout मॉडिफ़ायर या Layout कंपोज़ेबल के LayoutScope का हिस्सा होता है.

layoutDirection का इस्तेमाल करते समय, place का इस्तेमाल करके कंपोज़ेबल का प्लेसमेंट करें. इसे नापसंद करें placeRelative तरीका, लेआउट दिशा के आधार पर place नहीं बदलता है (बाएं से दाएं बनाम दाएं से बाएं).

पसंद के मुताबिक लेआउट इस्तेमाल किए जा रहे हैं

लेआउट और मॉडिफ़ायर के बारे में ज़्यादा जानने के लिए, Compose में बेसिक लेआउट, और आपको कस्टम लेआउट बनाने वाले सैंपल लिखें.

ज़्यादा जानें

Compose में कस्टम लेआउट के बारे में ज़्यादा जानने के लिए, यहां दी गई अतिरिक्त जानकारी देखें संसाधन.

वीडियो

{% endverba नया %} {% verbatim %}