مدل طرحبندی Compose به شما امکان میدهد از AlignmentLine
برای ایجاد خطوط تراز سفارشی استفاده کنید که میتواند توسط طرحبندیهای والدین برای تراز و قرار دادن فرزندانشان استفاده شود. به عنوان مثال، Row
می تواند از خطوط تراز سفارشی فرزندان خود برای تراز کردن آنها استفاده کند.
هنگامی که یک طرح بندی مقداری را برای یک AlignmentLine
خاص ارائه می کند، والدین طرح بندی می توانند این مقدار را پس از اندازه گیری با استفاده از عملگر Placeable.get
در نمونه Placeable
مربوطه بخوانند. بر اساس موقعیت AlignmentLine
، والدین می توانند در مورد موقعیت فرزندان تصمیم بگیرند.
برخی از composable ها در Compose از قبل با خطوط تراز ارائه می شوند. برای مثال، BasicText
قابل ترکیب خطوط تراز FirstBaseline
و LastBaseline
را در معرض دید قرار می دهد.
در مثال زیر، یک LayoutModifier
سفارشی به نام firstBaselineToTop
FirstBaseline
را میخواند تا از اولین خط پایه، به Text
اضافه کند.
شکل 1. تفاوت بین افزودن padding معمولی به یک عنصر و اعمال padding به خط پایه عنصر 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
composable سفارشی یا LayoutModifier
سفارشی، میتوانید خطوط همترازی سفارشی را ارائه کنید تا سایر کامپوزیپذیرهای والد بتوانند از آنها برای تراز کردن و قرار دادن فرزندان خود استفاده کنند.
مثال زیر یک BarChart
سفارشی را نشان میدهد که دو خط تراز، MaxChartValue
و MinChartValue
را نشان میدهد، بهطوریکه سایر قابل ترکیبها میتوانند با حداکثر و حداقل مقدار داده نمودار تراز شوند. دو عنصر متن، حداکثر و حداقل ، در مرکز خطوط تراز سفارشی تراز شده اند.
شکل 2. 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
و نقطه داده را می گیرد و دو متن را با حداکثر و حداقل مقادیر داده نمودار تراز می کند. پیشنمایش این ترکیبپذیر همان چیزی است که در شکل 2 نشان داده شده است.
@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) ) } }
برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- گرافیک در Compose
- طرحبندیهای سفارشی {:#custom-layouts }
- اندازهگیریهای ذاتی در طرحبندیهای Compose