Правила компоновки во Flutter, которые должен знать каждый

Когда новичок во Flutter спрашивает, почему какой-то виджет с width: 100 не ширины 100 пикселей, обычно ему отвечают, что надо обернуть этот виджет в Center, верно?

Если так отвечать, то к вам будут возвращаться снова и снова, спрашивая, почему какой-то FittedBox не работает, почему этот Column переполнен или как работает IntrinsicWidth.

Сначала объясните, что Flutter компоновка очень отличается от HTML компоновки (особенно, если говорите с веб-разработчиком), а затем скажите, что необходимо запомнить следующее правило:

Ограничения для виджетов объявляются в родителях. Размеры (желаемые) задаются в самом виджете. Позиция виджета на экране устанавливается родителем

На мой взгляд, это правило нужно изучить, как можно раньше, так как без него по-настоящему понять компоновку во Flutter нельзя.

Более детально:

  • Виджет получает свои ограничения от своего родителя. "Ограничение" — это всего 4 значения: минимальная и максимальная ширина, минимальная и максимальная высота.

  • Затем виджет проходит по своему списку детей. Виджет сообщает своим дочерним элементам, каковы их ограничения (которые могут быть разными для каждого ребенка), а затем спрашивает каждого ребенка, какого размера он "хочет" быть.

  • Затем виджет размещает свои дочерние элементы (горизонтально по оси x и вертикально по оси y) один за другим.

  • И, наконец, виджет сообщает своему родителю о собственном размере (в пределах исходных ограничений, конечно).

Например, виджет, похожий на столбец с некоторыми отступами, хочет расположить два дочерних элемента:

Виджет: Родитель, каковы мои ограничения? Родитель: Ты должен быть от 90 до 300 пикселей в ширину и от 30 до 85 в высоту. Виджет: Хм, так как я хочу иметь 5 пикселей отступа, то мои дети могут иметь не более 290 пикселей ширины и 75 пикселей высоты. Виджет: Первый ребенок, вы должны быть от 0 до 290 пикселей в ширину и от 0 до 75 в высоту. Первый ребенок: Хорошо, тогда я хочу быть 290 пикселей в ширину и 20 пикселей в высоту. Виджет: Хм, поскольку я хочу поместить своего второго ребенка ниже первого, это оставляет только 55 пикселей высоты для моего второго ребенка. Виджет: Эй, второй ребенок, ты должен быть от 0 до 290 в ширину и от 0 до 55 в высоту. Второй ребенок: Хорошо, я хочу быть 140 пикселей в ширину и 30 пикселей в высоту. Виджет: Очень хорошо. Я расположу своего первого ребенка в точке x: 5 и y: 5, а второго – в x: 80 и y: 25. Виджет: Родитель, я решил, что мой размер будет 300 пикселей в ширину и 60 пикселей в высоту.

Ограничения

В результате вышеописанного правила механизм компоновки Flutter имеет несколько важных ограничений:

  • Виджет может получить свой собственный размер только в пределах ограничений, заданных ему его родителем. Это означает, что виджет обычно не может иметь любой размер, какой он хочет.

  • Виджет не может знать о своем положении на экране и не определяет его, так как это решает его родитель.

  • Поскольку размер и положение родителя, в свою очередь, также зависит от его собственного родителя, невозможно точно определить размер и положение любого виджета, не принимая во внимание дерево в целом.

Примеры

Запустить CodePen ниже (сначала нужно нажать кнопку Run Pen, а затем кнопку Rerun, которая появится в правом нижнем углу экрана);

Остальные примеры

Last updated