Row, Column и Stack

Три виджета, которые отвечают за расположение всего остального на экране:

  • Row выстраивает потомков в горизонтальную линию — когда элементы должны стоять рядом.

  • Column укладывает их сверху вниз: сообщения в чате, поля формы, секции страницы.

  • Stack кладёт потомков слоями. Внутри Stack виджет можно поставить в произвольную точку относительно границ — так делаются подписи поверх фотографий и значки-счётчики.

Выбор между ними определяется тем, как элементы должны стоять относительно друг друга:

row-col-stack.png

совет
Меньше вложенности

Берите минимум строк и столбцов, которого хватает для нужной раскладки. Больше десяти уровней вложенности на странице или в компоненте — сигнал, что часть дерева пора вынести в компонент.

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

Главная ось

Главная ось — то направление, вдоль которого виджет расставляет потомков.

Row: главная ось горизонтальная, потомки идут слева направо.

Доступные значения Main Axis для Row:

row-main-axis.png

Main Axis у Row: Start, End, Center, SpaceEvenly, SpaceAround, SpaceBetween

Column: главная ось вертикальная, потомки идут сверху вниз.

Значения Main Axis для Column те же:

column-main-axis.png

Main Axis у Column: Start, End, Center, SpaceEvenly, SpaceAround, SpaceBetween

Главная ось определяет, как распределяется свободное место между потомками: собрать их в начале, развести по краям или разложить с равными промежутками.

Поперечная ось

Поперечная ось перпендикулярна главной и отвечает за выравнивание по второму направлению. Значений три: Start, Center, End.

Row: поперечная ось вертикальная — определяет положение потомков по высоте строки.

row-cross.png

Cross Axis у Row; Main Axis выставлена в Center

Column: поперечная ось горизонтальная — определяет положение потомков по ширине столбца.

column-cross.png

Cross Axis у Column; Main Axis выставлена в Center

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

У Stack осей в этом смысле нет: потомки позиционируются относительно всей его площади. За это отвечает свойство Default Child Alignment — координаты X и Y.

stack-align.png

Оси — то, из-за чего вёрстка чаще всего ведёт себя «не так»: элемент прижат к краю или растянут вопреки ожиданиям почти всегда из-за настроек Main Axis и Cross Axis родителя.

Expansion и Flex

Виджет, попавший внутрь Row или Column, получает дополнительные свойства Expansion и Flex. Они определяют, сколько свободного места он заберёт у родителя.

Expanded

Варианты Expansion:

  • Default — виджет не растягивается вдоль главной оси и занимает ровно столько, сколько требует содержимое.

  • Flexible — виджет может занять всё доступное место вдоль главной оси, но не обязан. По сути это «максимальная ширина, равная свободному месту»: если содержимое меньше, виджет останется меньше.

    внимание
    Ограничение

    Flexible недоступен, если родительский Row не ограничен по ширине, а Column — по высоте.

  • Expanded — виджет забирает всё свободное место вдоль главной оси.

совет
Expanded и Flexible на примере

expanded.png

  1. Поведение по умолчанию. Два потомка стоят рядом, каждый занимает ровно столько, сколько нужно его содержимому.

  2. Один Expanded. Первый потомок (выделен красным) обёрнут в Expanded и забирает всё, что осталось после остальных: он растягивается, остальные сжимаются до минимума.

  3. Все Expanded. Свободное место делится между потомками поровну, независимо от того, сколько занимает содержимое каждого.

  4. Все Flexible. Похоже на предыдущий случай, но с одним отличием: Flexible позволяет виджету стать меньше выделенной доли, если содержимому столько не нужно.

Ещё один пример, уже про Flexible:

совет
Зачем нужен Flexible

flexible.png

  • Слева у потомков 2 (фиолетовый) и 3 (зелёный) настройки по умолчанию — они держат свой естественный размер. Когда контейнер узкий, содержимое обрезается: сжиматься эти виджеты не умеют.

  • Справа те же потомки обёрнуты в Flexible и подстраиваются под ширину контейнера — растягиваются или сжимаются, и содержимое остаётся видимым на любом экране.

Flex

Флекс-фактор — целое число, задающее долю виджета относительно соседей. Место делится пропорционально сумме флекс-факторов всех потомков.

инфо
По умолчанию

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

С флекс-фактором виджет забирает свою долю свободного места. Если у одного потомка фактор 1, а у другого 2, второй займёт вдвое больше.

совет
Пример с флекс-факторами

flex.png

  • Потомок 2 (фиолетовый) с фактором 8 стабильно занимает большую часть строки.

  • У потомка 3 (зелёного) фактор меняется с 1 на 4 — он заметно расширяется, но всё равно уступает потомку 2.

Видеоразбор Expanded и Flexible:

Прокрутка

Свойство прокрутки у Row и Column решает, что делать, когда содержимое не помещается в отведённое место:

  • Allow Scrolling — содержимое может выходить за границы экрана или родителя, и до него можно доскроллить.

  • Do Not Allow Scrolling — содержимое обязано уместиться. Лишнее не отображается, а во время разработки вы увидите характерную жёлто-чёрную полосу переполнения.

совет
Что в коде

Включённая прокрутка означает, что Row или Column обёрнут в SingleChildScrollView(). Этот виджет подстраивает размер и положение потомка под входящие ограничения и берёт на себя обработку жеста.

Расстояния

  • Items Spacing — расстояние между соседними потомками в пикселях. Значение можно задать числом или взять из переменной.
совет
Items Spacing вместо отступов

Задавайте расстояние на родительском Row или Column, а не отступами у каждого потомка. Отступы разъезжаются, особенно там, где список собран вручную, а не сгенерирован.

  • Apply to Start & End — применить то же расстояние в начале и в конце: к промежуткам между потомками добавятся отступы по краям.

  • Start Spacing и End Spacing — отдельные значения для начала и конца, когда нужны поля, отличные от промежутков между элементами.

перевод официальной документации FlutterFlow

обновлено

ESC