Flutter에서의 Layout Widget은 앱의 UI를 구성하는 데 있어 핵심적인 역할을 합니다.
이들은 다양한 방식으로 Widget을 배치하고, 조정하여 원하는 디자인과 구조를 만들 수 있게 해줍니다.
주요 Layout Widget에 대하여 간단한 예시 코드와 함께 소개하겠습니다.
아래 예제의 전체 소스는 GitHub Repository 에 있습니다.
Container
소개
여백, 정렬, 크기 등을 설정할 수 있는 범용 Widget입니다.
속성
- padding: 자식과 컨테이너의 가장자리 사이의 여백.
- color: 컨테이너의 색상.
- decoration: 자식 뒤에 그려질 장식.
- margin: 컨테이너를 둘러싼 여백.
- width, height: 컨테이너의 크기.
- alignment: 컨테이너 내에서의 자식의 정렬.
예시 코드
200px x200px 의 배경이 파란 사각형 컨테이너를 생성하고, 안에 상하좌우 padding 20px을 주고 자식 widget으로 Text widget을 추가합니다.
Container( padding: const EdgeInsets.all(20.0), color: Colors.blue, width: 200, height: 200, child: const Text( 'Hello World', style: TextStyle( color: Colors.white, fontSize: 20, ), ), ),
결과
Row
소개
세로 방향으로 자식 Widget을 정렬합니다.
속성
- mainAxisAlignment: 주 축(로우의 경우 수평)을 따라 자식들이 배치되는 방식.
- crossAxisAlignment: 교차 축(로우의 경우 수직)을 따라 자식들이 배치되는 방식.
- mainAxisSize: 주 축이 차지해야 하는 공간의 양.
예시 코드
3개의 다른 색의 container를 수평 방향으로 나열합니다.
주축(main axis)는 균등한 간격으로 배치되고, 교차 축(cross axis)은 시작 부분에 맞추어 정렬됩니다.
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( color: Colors.red, width: 100, height: 100, ), Container( color: Colors.green, width: 100, height: 100, ), Container( color: Colors.blue, width: 100, height: 100, ), ], ),
결과
Column
소개
가로 방향으로 자식 Widget을 정렬합니다.
속성
- mainAxisAlignment: 주 축(컬럼의 경우 수직)을 따라 자식들이 배치되는 방식.
- crossAxisAlignment: 교차 축(컬럼의 경우 수평)을 따라 자식들이 배치되는 방식.
- mainAxisSize: 주 축이 차지해야 하는 공간의 양.
예시 코드
3개의 다른 색의 container를 수직 방향으로 나열합니다.
주축(main axis)는 균등한 간격으로 배치되고, 교차 축(cross axis)은 시작 부분에 맞추어 정렬됩니다.
Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( color: Colors.red, width: 100, height: 100, ), Container( color: Colors.green, width: 100, height: 100, ), Container( color: Colors.blue, width: 100, height: 100, ), ], ),
결과
Stack & Positioned
소개
Stack
Widget을 겹쳐서 배치합니다.
Positioned
Stack 내에서 Widget의 위치를 조정합니다.
속성
- alignment (Stack): 자식들이 서로 대비하여 어떻게 정렬될지.
- top, right, bottom, left (Positioned): 스택 내에서 자식의 정확한 위치.
예시 코드
하단으로 부터 10px 우측에서 부터 10px 떨어져서 Widget을 위치시켰습니다.
Stack( children: <Widget>[ Container( color: Colors.red, width: 200, height: 200, ), const Positioned( bottom: 10.0, right: 10.0, child: Text( 'On top of image', style: TextStyle(fontSize: 20, color: Colors.white), ), ), ], ),
결과
Expanded
소개
주로 Row
, Column
, 또는 Flex
같은 부모 위젯 내에서 사용됩니다.
자식 위젯을 확장하여 주변 공간을 채우게 하여, 주어진 방향(가로 또는 세로)으로 사용 가능한 공간을 모두 차지하도록 합니다.
속성
- flex: 사용 가능한 공간 내에서 자식 위젯이 차지하는 비율을 결정합니다. 모든
Expanded
위젯의flex
값을 합산하여, 각Expanded
위젯이 차지하는 공간의 비율을 계산합니다.
예시 코드
첫 번째와 두 번째 컨테이너는 각각 100px의 너비를 유지하는 반면, 세 번째 Expanded widget으로 감싸진 컨테이너는 나머지 공간을 모두 채우게 됩니다.
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( color: Colors.red, width: 100, height: 100, ), Container( color: Colors.green, width: 100, height: 100, ), Expanded( child: Container( color: Colors.blue, width: 100, height: 100, ), ), ], ),
결과
Flexible
소개
Row
, Column
, 또는 Flex
같은 부모 위젯 내에서 사용됩니다.
자식 Widget 에게 남은 공간을 어떻게 유연하게 배분합니다.
flex
속성을 사용하여 사용 가능한 공간 내에서 각 자식 Widget이 차지할 공간의 비율을 조정할 수 있으며, fit
속성으로 자식의 크기를 어떻게 조정할지 결정할 수 있습니다.
속성
- flex: 사용 가능한 공간 내에서 자식 Widget이 차지하는 비율을 결정합니다. 모든
Flexible
Widget의flex
값을 합산하여, 각Flexible
Widget이 차지하는 공간의 비율을 계산합니다. - fit:
FlexFit
을 사용하여 자식 Widget이 남은 공간을 어떻게 채울지 결정합니다.FlexFit.tight
는 자식이 할당된 공간을 모두 채우도록 합니다(이는Expanded
와 유사한 행동입니다), 반면에FlexFit.loose
는 자식 Widget이 필요한 만큼의 공간만 차지하도록 허용합니다.
예시 코드
Row의 자식 위젯들로 배치된 Flexible widget들은 주어진 flex
값에 해당하는 비율로 표시됩니다.
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Flexible( flex: 1, fit: FlexFit.tight, child: Container( color: Colors.red, height: 100, ), ), Flexible( flex: 2, fit: FlexFit.loose, child: Container( color: Colors.green, height: 100, ), ), Flexible( flex: 4, child: Container( color: Colors.blue, height: 100, ), ), ], ),
결과
Padding
소개
자식 Widget 주변에 여백을 추가합니다.
속성
- padding: 자식을 안쪽으로 들여쓸 공간의 양.
예시 코드
자식 위젯들을 주어진 값 만큼 띄어서 표시합니다.
body: Row( children: [ Padding( padding: const EdgeInsets.all(50.0), child: Container( color: Colors.red, width: 50, height: 50, ), ), Padding( padding: const EdgeInsets.all(30.0), child: Container( color: Colors.green, width: 50, height: 50, ), ), Padding( padding: const EdgeInsets.all(10.0), child: Container( color: Colors.blue, width: 50, height: 50, ), ), ], ),
결과
GridView
소개
격자 형태로 아이템을 배치합니다. 주로 이미지 갤러리, 제품 목록 등에 사용됩니다.
속성
- gridDelegate: 그리드의 레이아웃을 제어합니다.
- scrollDirection: 스크롤 뷰가 스크롤되는 축.
예시 코드
4개의 Container들을 1줄에 2개씩 표시합니다.
body: GridView.count( crossAxisCount: 2, children: [ Container( color: Colors.red, ), Container( color: Colors.green, ), Container( color: Colors.blue, ), Container( color: Colors.yellow, ), ], ),
결과
Wrap
소개
자식들을 수평 또는 수직 방향으로 배치하고, 공간이 부족하면 다음 줄로 넘깁니다.
속성
- direction: 주 축으로 사용할 방향.
- alignment: 한 줄 안에서 어떻게 자식들을 주 축에 배치할지.
- spacing: 각 자식 사이의 공간.
- runSpacing: 자식들의 각 실행(run) 사이의 공간입니다. 수평
Wrap
의 경우, 감싸기가 발생할 때 수직 공간을 제어합니다.
예시 코드
8px씩 사이를 주고 자식 widget들을 끝에 맞추어 배치하고 마지막 줄에 걸치면 자동 줄바꿈하여 다음 자식 Widget을 표시합니다.
const Wrap( spacing: 8.0, alignment: WrapAlignment.end, children: [ Chip( avatar: CircleAvatar( backgroundColor: Colors.orange, child: Text('AH', style: TextStyle(fontSize: 10)), ), label: Text('Hamilton'), ), Chip( avatar: CircleAvatar( backgroundColor: Colors.pink, child: Text('ML', style: TextStyle(fontSize: 10)), ), label: Text('Lafayette'), ), Chip( avatar: CircleAvatar( backgroundColor: Colors.lightBlue, child: Text('HM', style: TextStyle(fontSize: 10)), ), label: Text('Mulligan'), ), Chip( avatar: CircleAvatar( backgroundColor: Colors.green, child: Text('JL', style: TextStyle(fontSize: 10)), ), label: Text('Laurens'), ), ], ),
결과
ListView
소개
스크롤 가능한 세로 목록을 생성합니다.
속성
- scrollDirection: 리스트가 스크롤되는 축.
- padding: 자식들을 들여쓸 공간의 양.
예시 코드
자식 위젯들을 세로 방향으로 리스트 형식으로 표시합니다.
ListView( scrollDirection: Axis.vertical, padding: const EdgeInsets.all(16), children: <Widget>[ Container( color: Colors.red, width: 100, height: 100, ), Container( color: Colors.green, width: 100, height: 100, ), Container( color: Colors.blue, width: 100, height: 100, ), Container( color: Colors.yellow, width: 100, height: 100, ), Container( color: Colors.orange, width: 100, height: 100, ), Container( color: Colors.purple, width: 100, height: 100, ), ], ),
결과
SizedBox
소개
특정 크기의 공간을 만들 때 사용합니다.
주로 Widget 간의 간격을 조절할 때 사용하거나, 자식 Widget들의 크기를 제한할 수 있습니다.
속성
- width: 박스의 가로 너비
- height: 박스의 세로 길이
예시 코드
Width: 100px, Height: 100px 고정크기로 제한하는 Box를 생성합니다.
SizedBox( width: 100, height: 100, child: Container( width: 1000, height: 1000, color: Colors.red, ), ),
결과
SingleChildScrollView
소개
단일 자식을 스크롤 가능하게 만듭니다. 주로 긴 내용을 스크롤하여 볼 수 있게 할 때 사용됩니다.
속성
- scrollDirection: 스크롤 뷰가 스크롤되는 축.
예시 코드
50개 Container를 자식 Widget으로 갖는 Column을 세로 축으로 스크롤이 가능하게 합니다.
body: SingleChildScrollView( // scroll's direction is vertical (default) scrollDirection: Axis.vertical, child: Column( children: List.generate( 50, (index) => Container( height: 50, color: index % 2 == 0 ? Colors.yellow : Colors.pink, child: Center( child: Text('Item $index'), ), ), ), ), ),
결과
결론
위와 같이 다양하게 Widget들을 배치할 수 있는 Layout Widget들이 존재합니다.
각 Widget들만의 다양한 특성과 속성값들을 이용하여 원하는 Layout을 꾸며 볼 수 있습니다.