как использовать LayoutAlign в составлении реактивного ранца

Column(LayoutSize.Fill) {
        Box(
                modifier = LayoutSize(20.dp) + LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter,
                backgroundColor = Color.Blue
        )
        Box(
                LayoutSize(50.dp) + LayoutSize.Fill + LayoutAlign.CenterVertically,
                backgroundColor = Color.Blue
        )
    }

Я пробую этот образец LayoutAlign

но прямоугольники не отображаются

1 ответ

Решение

Быстрый ответ

Этот образец не работает из-за неправильного порядка модификаторов. Порядок модификаторов очень важен в Compose. Этот код будет работать так, как ожидалось:

Box(
    LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter + LayoutSize(20.dp),
    backgroundColor = Color.Blue
)

Почему не работает в исходном образце?

LayoutAlignвыравнивает содержимое в пределах границ, когда размер содержимого меньше его границ. Под капотом он сбрасывает ограничение минимального размера (minWidth, minHeightили и то, и другое, в зависимости от направления выравнивания), позволяя уменьшить размер содержимого и занимать его предпочтительный размер.

Boxс одним лишь цветом фона не обеспечивает какого-либо предпочтительного внутреннего размера его содержимого. Если разрешено быть всего лишь 0dp x 0dp - будет.

В правильном примере ограничения меняются под капотом следующим образом:

  1. LayoutSize.Min(40.dp, 40.dp)резервирует как минимум 40dp. Ограничения
    :minWidth = 40dp, maxWidth = infinity, minHeight = 40dp, maxHeight = infinity
  2. LayoutAlign.TopCenterприменяет выравнивание и сбрасывает ограничения минимального размера для обоих направлений.
    Ограничения:minWidth = 0dp, maxWidth = infinity, minHeight = 0dp, maxHeight = infinity
  3. LayoutSize(20.dp) приказывает, чтобы контент был размером ровно 20dp. minWidth а также minHeight здесь важны, без этого содержание Boxбудет измеряться как 0dp x 0xp.
    Ограничения:minWidth = 20dp, maxWidth = 20dp, minHeight = 20dp, maxHeight = 20dp.

Без последнего шага Boxсодержание будет измеряться как 0dp x 0dp. Это то, что происходит в исходном образце. Блок технически выровнен / расположен правильно в пределах 40dp, но он невидим, потому что его размер составляет 0dp x 0dp.

Использование LayoutAlign для элементов, которые имеют собственный предпочтительный размер

Имейте в виду, что если элемент знает, как измерить свое содержимое или предоставляет какой-то предпочтительный размер, он будет работать нормально, даже если мы не будем устанавливать какой-либо размер после применения LayoutAlign модификатор.

Пример:

Text("Text",
    modifier = LayoutSize.Min(40.dp, 40.dp) + LayoutAlign.TopCenter,
    style = TextStyle(fontSize = 8.sp)
)

Другие вопросы по тегам