

Constraint란?
Constraint 제약이라는 것이다.
어떤 제약이냐면 Widget의 위치와 사이즈와 크기에 대한 제약이다.
Constraint는 간단히 말해 위젯이 차지할 수 있는 최소 및 최대 너비와 높이를 정의하는 규칙이다.
부모 위젯은 자식 위젯에게 이러한 Constraint를 전달하고, 자식 위젯은 이 Constraint 내에서 자신의 크기를 결정한다.
Constraint는 위젯의 크기와 위치를 결정하는데 중요한 역할을 한다.
모든 Flutter 위젯은 자신의 크기와 위치를 결정할 때 부모 위젯으로부터 Constraint를 받는다(내부 코드적으로).
Constraint는 위젯이 가질 수 있는 최소/최대 너비와 높이를 지정하는 일종의 "규칙"이라고 볼 수 있다.
Constraint에는 다음과 같은 4가지 속성이 있다:
- minWidth: 위젯의 최소 너비
- maxWidth: 위젯의 최대 너비
- minHeight: 위젯의 최소 높이
- maxHeight: 위젯의 최대 높이
부모 위젯은 자식 위젯에게 이 4가지 속성을 조합한 Constraint를 제공한다.
Constraint의 유형
Flutter에는 크게 두 가지 유형의 Constraint가 있다.
1. Tight Constraint
Tight Constraint는 위젯의 크기를 고정하는 제약 조건이다.
minWidth와 maxWidth가 같고, minHeight와 maxHeight가 같은 경우를 Tight Constraint라고 부른다.
예를 들어 Container 위젯에 width와 height를 지정하면 Tight Constraint가 적용된다.
2. Loose Constraint
Loose Constraint는 위젯이 가질 수 있는 크기의 범위를 지정하는 제약 조건이다.
minWidth/minHeight와 maxWidth/maxHeight가 다른 경우를 Loose Constraint라고 한다.
예를 들어 Center 위젯은 자식 위젯에 Loose Constraint를 제공한다. (minWidth/minHeight는 0, maxWidth/maxHeight는 부모 위젯의 크기와 같음)
Constraint의 전파
부모 위젯은 자식 위젯에게 Constraint를 제공하고, 자식 위젯은 이 Constraint 내에서 자신의 크기를 결정한다.
자식 위젯이 또 다른 위젯을 포함한다면, 자신이 받은 Constraint를 자식에게 전파하는 식으로 레이아웃 트리 전체에 Constraint가 전파된다.
이 과정을 거쳐 최종적으로 모든 위젯의 크기와 위치가 결정되는 것이다.
Constraint 다루기 팁
- 가급적 자식 위젯에게 Loose Constraint를 제공하는 것이 좋다. 너무 엄격한 Constraint는 레이아웃을 경직되게 만든다.
- 자식 위젯의 크기를 직접 지정하기보다는 Flex, Expanded, ConstrainedBox 등의 위젯을 활용하는 것이 좋다.
- 위젯 트리가 깊어질수록 Constraint 전파를 이해하기 어려워진다. 상황에 맞는 적절한 위젯을 사용하고, 불필요하게 위젯을 중첩하지 않도록 한다.
Flutter 레이아웃의 4대 원칙
Flutter의 레이아웃 시스템은 매우 유연하고 강력하다.
하지만 처음 접하면 그 동작 방식이 직관적이지 않아 혼란스러울 수 있다.
사실 Flutter 레이아웃은 명확한 규칙에 따라 동작한다.
바로 Single Pass, Constraints Go Down, Sizes Go Up, Parent Sets Position이라는 4대 원칙이다.
Flutter 레이아웃 프로세스 개요
Flutter에서 화면을 그리는 과정은 크게 3단계로 이루어진다
- 위젯 트리 구성
- 레이아웃 (Constraints Go Down, Sizes Go Up)
- 페인팅
여기서 레이아웃 단계가 바로 우리가 집중할 부분이다. 레이아웃은 다시 다음과 같은 세부 과정을 거친다.
- 부모 위젯이 자식 위젯에게 Constraint를 전달 (Constraints Go Down)
- 자식 위젯이 주어진 Constraint 내에서 자신의 크기를 결정하고 부모에게 전달 (Sizes Go Up)
- 부모 위젯이 자식 위젯의 크기와 위치를 결정 (Parent Sets Position)
이 과정은 위젯 트리의 루트에서 리프까지 재귀적으로 한 번만 이루어진다. 이것이 바로 Single Pass의 의미이다.
1. Constraints Go Down
부모 위젯은 자식 위젯이 가질 수 있는 크기의 제약 조건(Constraint)을 자식에게 전달한다.
이는 위젯 트리의 위에서 아래로 전파된다.
예를 들어 Center 위젯은 자식에게 "부모의 크기 내에서 원하는 만큼 커질 수 있다"는 Constraint를 전달한다.
2. Sizes Go Up
자식 위젯은 부모에게 받은 Constraint를 만족하는 자신의 크기를 결정하고, 이를 부모에게 전달한다.
이는 위젯 트리의 아래에서 위로 전파된다.
예를 들어 Container 위젯은 부모의 Constraint를 받아들이고, width와 height 속성에 지정된 값을 이용해 자신의 크기를 결정한다. 그리고 이 크기 정보를 부모에게 전달한다.
3. Parent Sets Position
부모 위젯은 자식 위젯들로부터 받은 크기 정보를 바탕으로 자식 위젯의 위치를 결정한다.
예를 들어 Center 위젯은 자식의 크기를 받아들이고, 자식을 자신의 중앙에 위치시킨다.
Single Pass
위 과정은 위젯 트리의 루트에서 시작해 리프까지 내려갔다가 다시 루트로 돌아오는 단 한 번의 패스로 이루어진다.
즉, Constraint는 부모에서 자식으로 한 번만 전달되고 (Constraints Go Down), 크기는 자식에서 부모로 한 번만 전달됩니다 (Sizes Go Up). 모든 위젯의 크기가 결정되면 위치가 한 번에 결정되는 것이다 (Parent Sets Position).
이 Single Pass 방식 덕분에 Flutter 레이아웃은 매우 효율적으로 이루어질 수 있다.
제한 사항
Constraint, 레이아웃 원칙보다 아래 제한 사항들을 기억하면 된다.
- 자식 위젯은 부모 위젯이 제한하고 있는 constraint 내부에서만 크기를 가져갈 수 있다.
- 위젯의 위치는 부모 위젯이 지정하기 때문에 위젯은 자신이 정확히 어디에 위치될지 알 수 없다. (플러터에서 x, y 좌표로 위젯을 배치하지 않는 이유)
- 자식 위젯이 어디에 정렬돼야하는지 정확히 알 수 없는 경우에는 자식 위젯의 크기가 무시 될 수 있다.
'Flutter 초급' 카테고리의 다른 글
Stack(LIFO)과 Queue(FIFO) (0) | 2024.09.11 |
---|---|
Align (0) | 2024.09.10 |
DatePicker (0) | 2024.09.10 |
Dialog 띄우기 (0) | 2024.09.08 |
테마 (0) | 2024.09.08 |

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!