Column, Row и Box
Разбираем три кита раскладки в Compose: вертикальный Column, горизонтальный Row и наслаивающий Box.
Column размещает дочерние элементы сверху вниз, Row — слева направо, Box накладывает их друг на друга.
Column — вертикально
Column ставит детей друг под другом. Это самый частый контейнер для экрана:
Column {
Text("Строка 1")
Text("Строка 2")
Text("Строка 3")
}ASCII-результат
+-----------+ | Строка 1 | | Строка 2 | | Строка 3 | +-----------+
По умолчанию Column занимает по высоте ровно столько, сколько нужно содержимому, и прижимает детей к верхнему краю. Чтобы он растянулся на весь экран, ему дают Modifier.fillMaxSize(), а распределение детей задают через verticalArrangement — об этом в следующем уроке.
Row — горизонтально
Row ставит детей в ряд:
Row {
Text("A")
Text("B")
Text("C")
}+-----------+ | A B C | +-----------+
Box — наслоение
Box кладёт детей друг на друга, как стопку. Порядок в коде задаёт порядок слоёв: первый ребёнок — внизу, последний — сверху. Удобно для значка поверх картинки или текста по центру фона:
Box {
Image(painter = bg, contentDescription = null)
Text("Поверх картинки")
}У Box есть параметр contentAlignment, который выравнивает детей внутри: например, Alignment.Center поставит текст по центру картинки, а Alignment.BottomEnd — в правый нижний угол. Отдельным детям можно задать своё выравнивание через Modifier.align(...) — это работает только внутри Box.
Как работает под капотом
Раскладочные composable работают в два шага. Сначала фаза измерения: контейнер спрашивает у каждого ребёнка его желаемый размер. Затем фаза размещения: контейнер расставляет детей по своим правилам — Column вниз, Row вправо, Box в одну точку с наслоением. В отличие от старой View-системы Compose измеряет дерево за один проход, без дорогих повторных замеров.
Частые ошибки
- Использовать
Boxтам, где нуженColumn— элементы наложатся друг на друга вместо списка. - Вкладывать множество
ColumnвColumnбез необходимости — лишняя глубина дерева. - Забывать, что без модификаторов размера контейнер занимает ровно столько, сколько нужно содержимому (
wrap content).
Итог
Column— вертикальная раскладка,Row— горизонтальная,Box— наслоение.- Раскладка идёт в два шага: измерение и размещение.
- Контейнер по умолчанию подстраивается под размер содержимого.