Выравнивание, вес и Spacer

Учимся управлять выравниванием детей, распределять свободное место через weight и добавлять пустоты через Spacer.

Arrangement управляет распределением детей вдоль главной оси, а Alignment — их выравниванием поперёк неё.

Выравнивание

У Column есть horizontalAlignment (как выровнять детей по горизонтали) и verticalArrangement (как распределить по вертикали). У Row — наоборот:

Column(
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    Text("По центру")
    Text("С отступом 8dp между строками")
}

Arrangement.spacedBy(8.dp) добавляет равные промежутки между детьми — удобно вместо ручных отступов у каждого. Полезно держать в голове разницу осей: у Column главная ось вертикальная, поэтому verticalArrangement распределяет детей по высоте, а horizontalAlignment прижимает их влево/по центру/вправо. У Row всё зеркально: horizontalArrangement распределяет по ширине, verticalAlignment выравнивает по высоте. Среди значений Arrangement часто нужны Center, SpaceBetween (раздвинуть к краям) и SpaceAround.

Вес (weight)

Modifier.weight() распределяет свободное место между детьми пропорционально. Если два элемента в Row имеют weight(1f), они займут по половине ширины:

Row {
    Text("Левая", modifier = Modifier.weight(1f))
    Text("Правая", modifier = Modifier.weight(2f))
}

Здесь правая часть получит вдвое больше места (вес 2 против 1). Это аналог «гибких» колонок из CSS Flexbox.

ASCII-схема веса

|<-- 1 -->|<------ 2 ------>|
| Левая   | Правая          |

Spacer — управляемая пустота

Spacer — это пустой элемент, который занимает место. Им раздвигают компоненты:

Row {
    Text("Слева")
    Spacer(modifier = Modifier.weight(1f))
    Text("Справа")
}

Здесь Spacer с весом съедает всё свободное место, прижимая один текст к левому краю, другой — к правому.

Как работает под капотом

Дети с weight измеряются в особом порядке: сначала Compose выясняет размеры элементов без веса, вычитает их из общей длины, а остаток делит между взвешенными детьми пропорционально их весам. Поэтому weight работает только внутри Row и Column — там, где есть понятие главной оси и свободного места.

Частые ошибки

  • Ждать, что weight сработает в Box — там нет главной оси, вес неприменим.
  • Расставлять кучу Spacer фиксированного размера вместо Arrangement.spacedBy для равных промежутков.
  • Путать ось: у Column horizontalAlignment выравнивает поперёк, а распределение по вертикали — это verticalArrangement.

Итог

  • Alignment выравнивает поперёк оси, Arrangement распределяет вдоль неё.
  • Modifier.weight делит свободное место пропорционально (только в Row/Column).
  • Spacer — управляемая пустота; с весом он раздвигает соседей.
Проверьте себя
1. Что делает Modifier.weight в Row или Column?
AЗадаёт абсолютный размер в dp
BРаспределяет свободное место между детьми пропорционально весам
CМеняет цвет элемента
DРаботает в любом контейнере, включая Box
2. Как удобнее всего добавить равные промежутки между детьми Column?
AПоставить Spacer фиксированного размера после каждого
BИспользовать Arrangement.spacedBy
CЗадать каждому ребёнку отдельный padding
DЭто невозможно в Compose