Compose लेआउट मॉडल की मदद से, AlignmentLine का इस्तेमाल करके कस्टम अलाइनमेंट लाइन बनाई जा सकती हैं. इनका इस्तेमाल पैरंट लेआउट, अपने चाइल्ड लेआउट को अलाइन करने और उनकी पोज़िशन तय करने के लिए कर सकते हैं. उदाहरण के लिए, Row, अपने चाइल्ड व्यू को अलाइन करने के लिए, उनकी कस्टम अलाइनमेंट लाइनों का इस्तेमाल कर सकता है.
जब कोई लेआउट किसी खास AlignmentLine के लिए वैल्यू देता है, तो लेआउट के पैरंट, मेज़रमेंट के बाद इस वैल्यू को पढ़ सकते हैं. इसके लिए, उन्हें संबंधित Placeable इंस्टेंस पर Placeable.get ऑपरेटर का इस्तेमाल करना होगा. AlignmentLine की पोज़िशन के आधार पर, माता-पिता यह तय कर सकते हैं कि बच्चों को कहां बिठाना है.
Compose में कुछ कंपोज़ेबल, अलाइनमेंट लाइनों के साथ पहले से मौजूद होते हैं. उदाहरण के लिए, BasicText कंपोज़ेबल, FirstBaseline और LastBaseline अलाइनमेंट लाइन दिखाता है.
नीचे दिए गए उदाहरण में, firstBaselineToTop नाम का कस्टम LayoutModifier, FirstBaseline को पढ़ता है, ताकि Text में पैडिंग जोड़ी जा सके. यह पैडिंग, इसकी पहली बेसलाइन से शुरू होती है.
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) } } @Preview @Composable private fun TextWithPaddingToBaseline() { MaterialTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } }
उदाहरण में FirstBaseline को पढ़ने के लिए, मेज़रमेंट फ़ेज़ में placeable [FirstBaseline] का इस्तेमाल किया जाता है.
पसंद के मुताबिक अलाइनमेंट लाइनें बनाना
कस्टम Layout कंपोज़ेबल या कस्टम LayoutModifier बनाते समय, कस्टम अलाइनमेंट लाइनें दी जा सकती हैं. इससे, अन्य पैरंट कंपोज़ेबल, अपने चाइल्ड कंपोज़ेबल को अलाइन और पोज़िशन करने के लिए, उनका इस्तेमाल कर सकते हैं.
यहां दिए गए उदाहरण में, कस्टम BarChart कंपोज़ेबल दिखाया गया है. इसमें दो अलाइनमेंट लाइनें, MaxChartValue और MinChartValue दिखती हैं, ताकि अन्य कंपोज़ेबल, चार्ट की ज़्यादा से ज़्यादा और कम से कम डेटा वैल्यू के हिसाब से अलाइन हो सकें. दो टेक्स्ट एलिमेंट, ज़्यादा से ज़्यादा और कम से कम को कस्टम अलाइनमेंट लाइनों के बीच में अलाइन किया गया है.
BarChart कंपोज़ेबल, जिसमें टेक्स्ट को डेटा की ज़्यादा से ज़्यादा और कम से कम वैल्यू के हिसाब से अलाइन किया गया है.कस्टम अलाइनमेंट लाइन को आपके प्रोजेक्ट में टॉप-लेवल वैरिएबल के तौर पर तय किया जाता है.
/** * AlignmentLine defined by the maximum data value in a [BarChart] */ private val MaxChartValue = HorizontalAlignmentLine(merger = { old, new -> min(old, new) }) /** * AlignmentLine defined by the minimum data value in a [BarChart] */ private val MinChartValue = HorizontalAlignmentLine(merger = { old, new -> max(old, new) })
उदाहरण के लिए, कस्टम अलाइनमेंट लाइनें HorizontalAlignmentLine टाइप की हैं, क्योंकि इनका इस्तेमाल चाइल्ड व्यू को वर्टिकल तौर पर अलाइन करने के लिए किया जाता है. अगर एक से ज़्यादा लेआउट इन अलाइनमेंट लाइनों के लिए वैल्यू देते हैं, तो मर्ज करने की नीति को पैरामीटर के तौर पर पास किया जाता है. Compose लेआउट सिस्टम के कोऑर्डिनेट और Canvas कोऑर्डिनेट, [0, 0], सबसे ऊपर बाएं कोने को दिखाते हैं. साथ ही, x और y ऐक्सिस, नीचे की ओर पॉज़िटिव होते हैं. इसलिए, MaxChartValue वैल्यू हमेशा MinChartValue से छोटी होगी. इसलिए, चार्ट डेटा की सबसे ज़्यादा वैल्यू वाली बेसलाइन के लिए, मर्ज करने की नीति min है. वहीं, चार्ट डेटा की सबसे कम वैल्यू वाली बेसलाइन के लिए, मर्ज करने की नीति max है.
कस्टम Layout या LayoutModifier बनाते समय, MeasureScope.layout तरीके में कस्टम अलाइनमेंट लाइनें तय करें. यह तरीका, alignmentLines: Map<AlignmentLine, Int> पैरामीटर लेता है.
@Composable private fun BarChart( dataPoints: List<Int>, modifier: Modifier = Modifier, ) { val maxValue: Float = remember(dataPoints) { dataPoints.maxOrNull()!! * 1.2f } BoxWithConstraints(modifier = modifier) { val density = LocalDensity.current with(density) { // ... // Calculate baselines val maxYBaseline = // ... val minYBaseline = // ... Layout( content = {}, modifier = Modifier.drawBehind { // ... } ) { _, constraints -> with(constraints) { layout( width = if (hasBoundedWidth) maxWidth else minWidth, height = if (hasBoundedHeight) maxHeight else minHeight, // Custom AlignmentLines are set here. These are propagated // to direct and indirect parent composables. alignmentLines = mapOf( MinChartValue to minYBaseline.roundToInt(), MaxChartValue to maxYBaseline.roundToInt() ) ) {} } } } } }
इस कंपोज़ेबल के डायरेक्ट और इनडायरेक्ट पैरेंट, अलाइनमेंट लाइनों का इस्तेमाल कर सकते हैं. यहां दिया गया कंपोज़ेबल, एक कस्टम लेआउट बनाता है. यह लेआउट, पैरामीटर के तौर पर दो Text स्लॉट और डेटा पॉइंट लेता है. साथ ही, दोनों टेक्स्ट को चार्ट की ज़्यादा से ज़्यादा और कम से कम डेटा वैल्यू के हिसाब से अलाइन करता है. इस कंपोज़ेबल की झलक, दूसरी इमेज में दिखाई गई है.
@Composable private fun BarChartMinMax( dataPoints: List<Int>, maxText: @Composable () -> Unit, minText: @Composable () -> Unit, modifier: Modifier = Modifier, ) { Layout( content = { maxText() minText() // Set a fixed size to make the example easier to follow BarChart(dataPoints, Modifier.size(200.dp)) }, modifier = modifier ) { measurables, constraints -> check(measurables.size == 3) val placeables = measurables.map { it.measure(constraints.copy(minWidth = 0, minHeight = 0)) } val maxTextPlaceable = placeables[0] val minTextPlaceable = placeables[1] val barChartPlaceable = placeables[2] // Obtain the alignment lines from BarChart to position the Text val minValueBaseline = barChartPlaceable[MinChartValue] val maxValueBaseline = barChartPlaceable[MaxChartValue] layout(constraints.maxWidth, constraints.maxHeight) { maxTextPlaceable.placeRelative( x = 0, y = maxValueBaseline - (maxTextPlaceable.height / 2) ) minTextPlaceable.placeRelative( x = 0, y = minValueBaseline - (minTextPlaceable.height / 2) ) barChartPlaceable.placeRelative( x = max(maxTextPlaceable.width, minTextPlaceable.width) + 20, y = 0 ) } } } @Preview @Composable private fun ChartDataPreview() { MaterialTheme { BarChartMinMax( dataPoints = listOf(4, 24, 15), maxText = { Text("Max") }, minText = { Text("Min") }, modifier = Modifier.padding(24.dp) ) } }
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर, लिंक टेक्स्ट दिखता है
- Compose में ग्राफ़िक
- कस्टम लेआउट {:#custom-layouts }
- Compose लेआउट में इंट्रिन्सिक मेज़रमेंट