Линии выравнивания в Jetpack Compose

Модель макета Compose позволяет использовать AlignmentLine для создания пользовательских линий выравнивания, которые могут использоваться родительскими макетами для выравнивания и расположения дочерних элементов. Например, Row может использовать пользовательские линии выравнивания своих дочерних элементов для их выравнивания.

Когда макет предоставляет значение для определенного AlignmentLine , родители макета могут прочитать это значение после измерения, используя оператор Placeable.get в соответствующем экземпляре Placeable . Основываясь на положении AlignmentLine , родители могут затем решить, где расположить детей.

Некоторые составные элементы в Compose уже имеют линии выравнивания. Например, составной элемент BasicText предоставляет линии выравнивания FirstBaseline и LastBaseline .

В приведенном ниже примере пользовательский LayoutModifier под названием firstBaselineToTop считывает FirstBaseline , чтобы добавить дополнение к Text начиная с его первой базовой линии.

Рисунок 1. Показана разница между добавлением обычного заполнения к элементу и применением заполнения к базовой линии текстового элемента.

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 , чтобы другие составные элементы могли выравниваться по максимальному и минимальному значению данных диаграммы. Два текстовых элемента, Max и Min , были выровнены по центру пользовательских линий выравнивания.

Рис. 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)
       
)
   
}
}

{% дословно %}

Пока рекомендаций нет.

Попытайтесь в свой аккаунт Google.

{% endverbatim %} ,

Модель макета Compose позволяет использовать AlignmentLine для создания пользовательских линий выравнивания, которые могут использоваться родительскими макетами для выравнивания и расположения дочерних элементов. Например, Row может использовать пользовательские линии выравнивания своих дочерних элементов для их выравнивания.

Когда макет предоставляет значение для определенного AlignmentLine , родители макета могут прочитать это значение после измерения, используя оператор Placeable.get в соответствующем экземпляре Placeable . Основываясь на положении AlignmentLine , родители могут затем решить, где расположить детей.

Некоторые составные элементы в Compose уже имеют линии выравнивания. Например, составной элемент BasicText предоставляет линии выравнивания FirstBaseline и LastBaseline .

В приведенном ниже примере пользовательский LayoutModifier под названием firstBaselineToTop считывает FirstBaseline , чтобы добавить дополнение к Text начиная с его первой базовой линии.

Рисунок 1. Показана разница между добавлением обычного заполнения к элементу и применением заполнения к базовой линии текстового элемента.

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 , чтобы другие составные элементы могли выравниваться по максимальному и минимальному значению данных диаграммы. Два текстовых элемента, Max и Min , были выровнены по центру пользовательских линий выравнивания.

Рис. 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)
       
)
   
}
}

{% дословно %}

Пока рекомендаций нет.

Попытайтесь в свой аккаунт Google.

{% endverbatim %} ,

Модель макета Compose позволяет использовать AlignmentLine для создания пользовательских линий выравнивания, которые могут использоваться родительскими макетами для выравнивания и расположения дочерних элементов. Например, Row может использовать пользовательские линии выравнивания своих дочерних элементов для их выравнивания.

Когда макет предоставляет значение для определенного AlignmentLine , родители макета могут прочитать это значение после измерения, используя оператор Placeable.get в соответствующем экземпляре Placeable . Основываясь на положении AlignmentLine , родители могут затем решить, где расположить детей.

Некоторые составные элементы в Compose уже имеют линии выравнивания. Например, составной элемент BasicText предоставляет линии выравнивания FirstBaseline и LastBaseline .

В приведенном ниже примере пользовательский LayoutModifier под названием firstBaselineToTop считывает FirstBaseline , чтобы добавить дополнение к Text начиная с его первой базовой линии.

Рисунок 1. Показана разница между добавлением обычного заполнения к элементу и применением заполнения к базовой линии текстового элемента.

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 , чтобы другие составные элементы могли выравниваться по максимальному и минимальному значению данных диаграммы. Два текстовых элемента, Max и Min , были выровнены по центру пользовательских линий выравнивания.

Рис. 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)
       
)
   
}
}

{% дословно %}

Пока рекомендаций нет.

Попытайтесь в свой аккаунт Google.

{% endverbatim %} ,

Модель макета Compose позволяет использовать AlignmentLine для создания пользовательских линий выравнивания, которые могут использоваться родительскими макетами для выравнивания и расположения дочерних элементов. Например, Row может использовать пользовательские линии выравнивания своих дочерних элементов для их выравнивания.

Когда макет предоставляет значение для определенного AlignmentLine , родители макета могут прочитать это значение после измерения, используя оператор Placeable.get в соответствующем экземпляре Placeable . Основываясь на положении AlignmentLine , родители могут затем решить, где расположить детей.

Некоторые составные элементы в Compose уже имеют линии выравнивания. Например, составной элемент BasicText предоставляет линии выравнивания FirstBaseline и LastBaseline .

В приведенном ниже примере пользовательский LayoutModifier под названием firstBaselineToTop считывает FirstBaseline , чтобы добавить дополнение к Text начиная с его первой базовой линии.

Рисунок 1. Показана разница между добавлением обычного заполнения к элементу и применением заполнения к базовой линии текстового элемента.

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 , чтобы другие составные элементы могли выравниваться по максимальному и минимальному значению данных диаграммы. Два текстовых элемента, Max и Min , были выровнены по центру пользовательских линий выравнивания.

Рис. 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)
       
)
   
}
}

{% дословно %}

Пока рекомендаций нет.

Попытайтесь в свой аккаунт Google.

{% дословно %}