Flutter Constraint와 Layout
Flutter는 3단계를 거쳐 widget의 layout을 결정한다.
- Constraints go down : Parent widget이 child widget에 constraint를 제안한다.
- Sizes go up : Child widget은 constraint 범위 내의 size를 parent widget에 알려준다.
- Parent sets position : Parent widget은 자신의 alignment 정보와 child widget size를 사용해서 child widget의 position을 결정한다.
여기서 “constraint“란 size의 최대 ~ 최소값의 범위를 말한다. Flutter에서는 BoxConstraints
class를 주로 사용하여 minWidth
, minHeight
, maxWidth
, maxHeight
을 정의한다.
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity,
});
여기서 주의할 점은, constraint는 size의 범위를 제한하는 것이므로 child widget의 size 또한 이 constraint 범위 안에 있어야 한다는 것이다. Child widget size가 parent가 제안한 constraint 범위를 벗어나면 “A RenderFlex overflowed…” error가 발생한다.
Tight vs loose constraints
Tight constraint
min == max
인 경우로, exact size를 갖게 만든다.BoxConstraints.tight(Size size) : minWidth = size.width, maxWidth = size.width, minHeight = size.height, maxHeight = size.height;
App
widget은 child widget을 전체 screen에 딱 맞게 만드는데, screen size에 대한 tight constraint가 적용된 것임
Loose constraint
min == 0 < max
인 경우로, child widget이 범위 내에서 own size를 가질 수 있게 한다.Center
widget은 parent로부터 받은 tight constraint를 loose constraint로 바꿔서 child에 전달하는 목적이기도 함
Bounded vs Unbounded
Bounded constraint
max < infinity
인 경우- Widget 크기가 min ~ max 범위 안에서 결정됨
Unbounded constraint
max == infinity
인 경우- Size 제약이 없는 상태이므로 box는 가능한 최대 size로 커지려고 한다.
Column
,Row
같은Flex
box 또는ListView
,ScrollView
subclass들 같은 scrollable region이 unbounded constraint를 갖는다.- 발생할 수 있는 문제
ListView
의 scroll 영역은 main axis 방향으로 무한대 크기를 허용함children
중 main axis와 같은 방향으로 크기가 무한대로 확장하는 widget이 있다면 unbound layout error가 발생한다.- e.g. 크기가 고정되지 않은
ListView
안에서Column
,Row
등 flexible widget 사용
- e.g. 크기가 고정되지 않은
- 둘 중 하나는
SizedBox
로 크기를 고정하거나BoxConstraint
로 제약을 추가해야 한다.
Flutter Widgets들의 Size 규칙
Flutter widget들이 size를 결정하는 규칙은 아래와 같다.
- 가능한 영역을 꽉 채우는 size를 사용하는 widget (e.g.
Center
,Align
,ListView
) - Child widget과 동일한 size를 사용하는 widget (e.g.
Transform
,Opacity
) - Content size를 사용하는 widget (e.g.
Image
,Text
)
특히, Container
widget은 어떤 속성을 사용하는지에 따라 동작하는 방식이 달라진다.
- 기본적으로 가능한 영역을 꽉 채우는 size를 사용한다. (1번)
width
,height
등 size가 지정되면 해당 size를 사용한다. (3번)child
widget을 갖는 경우, child widget size를 사용한다. (2번)