Правила компоновки во Flutter, которые должен знать каждый
Last updated
Last updated
Когда новичок во 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
, которая появится в правом нижнем углу экрана);
Остальные примеры