본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.
책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.
가로로 배치하기 — Row
레이아웃 위젯은 Row와 Column이 대표적입니다. 먼저 Row는 가로 방향으로 위젯을 배치합니다. 예를 들어 다음 코드는 Row에 Container 2개를 추가한 예입니다. 자신의 하위에 추가할 위젯이 하나라면 Center처럼 child에 하지만, 여러 개를 추가하는 Row, Column 같은 위젯은 children에 추가합니다.
책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.
Row(
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
)
],
),
세로로 배치하기 — Column
앞에서 예로 든 Container 2개를 Column에 추가하면 다음처럼 세로로 배치합니다.
Column(
children: [
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
)
],
),
레이아웃 중첩하기
앞에서 살펴본 Row와 Column으로 위젯을 가로나 세로로 배치할 수 있지만 대부분 화면은 그렇게 단순하지 않습니다. 예를 들어 다음처럼 인스타그램 같은 화면을 구성한다고 가정하면 크게 4개 영역으로 나누어 설계할 수 있습니다.
top 영역에는 아이콘, 문자열 등이 가로로 배치되었고 그 아래 이미지가 출력되며 icons 영역에는 아이콘 4개가 가로로 출력됩니다. 그리고 마지막 bottom 부분에 문자열 2개가 세로로 나열됩니다.
이 화면은 Row와 Column을 한 번만 사용하면 안 되고 중첩해야 합니다. 즉, Row나 Column 하위에 다른 Row, Column을 추가해야 합니다. 예를 들어 다음처럼 구성할 수 있습니다.
즉, 레이아웃도 하나의 위젯이므로 다른 레이아웃 하위에 추가할 수 있습니다. 이런 식으로 레이아웃을 중첩해서 원하는 화면을 구성합니다.
Column(
children: [
Row(
children: [
Image(... (생략) ...),
Text(... (생략) ...),
PopupMenuButton(... (생략) ...)
],
)
Image(... (생략) ...),
Row(
children: [
Image(... (생략) ...),
Image(... (생략) ...),
Image(... (생략) ...),
Image(... (생략) ...),
],
),
Column(
children: [
Text(... (생략) ...),
Text(... (생략) ...),
],
)
],
),
크기 설정하기 — mainAxisSize
Row와 Column은 기본축main axis과 교차축cross axis이라는 2개의 축이 있습니다. Row는 위젯을 가로로 배치하므로 가로 방향이 기본축이며 세로 방향이 교차축입니다. 반면에 Column은 위젯을 세로로 배치하므로 세로 방향이 기본축이며 가로 방향이 교차축입니다. Row나 Column으로 위젯을 배치하면서 크기나 정렬을 조정할 때 이러한 축 개념을 이용합니다.
먼저 Row나 Column이 차지하는 크기를 조정하는 방법을 살펴보겠습니다. Row나 Column에 크기를 설정하지 않으면 기본축 크기는 차지할 수 있는 최대로 설정되며, 교차축은 추가된 위젯을 출력할 최소 크기로 설정됩니다.
다음 코드에서는 Row가 차지하는 영역을 노란색으로 칠하고 그 안에 위젯을 3개 추가했습니다. 실행 결과를 보면 Row의 가로는 전체를 차지하며, 세로는 자신에게 추가된 위젯 가운데 세로로 가장 큰 위젯의 크기만큼만 차지하는 것을 알 수 있습니다.
Container(
color: Colors.yellow,
child: Row(
children: [
Container(
width: 50, height: 100, color: Colors.red,
),
Container(
width: 50, height: 50, color: Colors.green,
),
Container(
width: 50, height: 150, color: Colors.blue,
),
],
),
)
Row나 Column의 기본축 크기를 조정하는 속성은 mainAxisSize입니다. mainAxisSize에는 MainAxisSize.max나 MainAxisSize.min값을 설정할 수 있는데 전자는 최대 크기, 후자는 출력할 위젯의 크기만큼을 의미합니다.
다음 코드에서는 mainAxisSize 속성에 MainAxisSize.min을 설정하여 Row에 포함된 위젯을 출력할 수 있을 정도의 가로 크기를 차지합니다.
Container(
color: Colors.yellow,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
... (생략) ...
],
),
)
배치 설정하기 — Alignment
배치alignment는 Row나 Column에 추가하는 위젯을 어떻게 배치할 것인지를 정할 때 사용합니다. Row와 Column의 기본 배치는 가로와 세로지만 대상 위젯의 크기가 다를 때는 가운데 정렬할지 아니면 시작이나 끝부터 배치할지를 정할 수 있습니다. 이때 Alignment를 사용합니다.
배치를 설정하지 않으면 기본축은 start이며 교차축은 center입니다. 기본축 배치를 설정한다면 mainAxisAlignment 속성에 다음과 같은 MainAxisAlignment 클래스의 상수를 이용합니다.
•center: 중앙에 배치
•end: 끝에 배치
•start: 시작에 배치
•spaceAround: 각 위젯의 앞뒤 공백을 균등하게 배치
•spaceBetween: 위젯 간 공백을 균등하게 배치
•spaceEvenly: 앞뒤 그리고 각 위젯 간 공백을 균등하게 배치
교차축 배치도 설정할 수 있으며 crossAxisAlignment 속성에 다음과 같은 CrossAxisAlignment 클래스의 상수를 이용합니다.
•baseline: 기준선에 맞춰 배치
•center: 가운데에 배치
•end: 끝에 배치
•start: 시작에 배치
•stretch: 교차축을 모두 차지하게 배치
mainAxisAlignment와 crossAxisAlignment값을 조정해 보겠습니다. 다음 코드는 main AxisAlignment 속성에 MainAxisAlignment.center값을 설정하여 위젯을 기본축 가운데에 배치하며, crossAxisAlignment 속성에 CrossAxisAlignment.start값을 설정하여 위젯을 위쪽(시작)에 붙여서 배치합니다.
Container(
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(width: 50, height: 100, color: Colors.red,),
Container(width: 50, height: 50, color: Colors.green,),
Container(width: 50, height: 150, color: Colors.blue,),
],
),
)
이번에는 MainAxisAlignment 클래스의 spaceBetween, spaceAround, spaceEvenly를 알아보겠습니다. spaceBetween은 각 위젯 사이의 공백을 균등한 크기로 설정하며, spaceAround는 각 위젯의 앞뒤 공백을 균등한 크기로 설정합니다. 그리고 spaceEvenly는 전체 위젯의 앞뒤 공백과 각 위젯 사이의 공백을 균등한 크기로 설정합니다.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(width: 50, height: 50, color: Colors.red,),
Container(width: 50, height: 50, color: Colors.green,),
Container(width: 50, height: 50, color: Colors.blue,),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(width: 50, height: 50, color: Colors.red,),
Container(width: 50, height: 50, color: Colors.green,),
Container(width: 50, height: 50, color: Colors.blue,),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 50, height: 50, color: Colors.red,),
Container(width: 50, height: 50, color: Colors.green,),
Container(width: 50, height: 50, color: Colors.blue,),
],
),
이번에는 교차축의 배치 설정을 알아보겠습니다. crossAxisAlignment 속성에 CrossAxis Alignment.start를 설정하면 위젯을 교차축의 시작 위치에 배치하며, CrossAxisAlignment.end를 설정하면 끝 위치에 배치합니다. 그리고 CrossAxisAlignment.stretch는 각 위젯에 설정된 교차축 크기를 무시하고 전체 공간을 차지하도록 확대합니다.
Container(
margin: EdgeInsets.only(bottom: 5),
color: Colors.grey,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
... (생략) ...
],
)
),
Container(
color: Colors.grey,
margin: EdgeInsets.only(bottom: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
... (생략) ...
],
)
),
Container(
color: Colors.grey,
margin: EdgeInsets.only(bottom: 5),
height: 200,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
... (생략) ...
],
)
),
겹쳐서 모두 보이기 — Stack
Stack은 위젯을 겹쳐서 배치할 때 사용합니다. Stack의 children 속성에 위젯을 추가하면 추가된 순서대로 겹쳐서 출력됩니다. 다음 코드는 Stack에 색상을 다르게 한 Container 3개를 추가한 예입니다. 첫 번째 빨간색 Container가 먼저 출력되고, 그 위에 두 번째로 추가한 녹색 Container가, 그리고 세 번째 노란색 Container가 겹쳐서 출력됩니다.
Stack(
children: [
Container(
color: Colors.red,
),
Container(
width: 300,
height: 300,
color: Colors.green,
),
Container(
width: 150,
height: 150,
color: Colors.yellow,
)
],
),
Stack이 차지하는 크기는 children에 추가한 위젯 중 가장 큰 위젯의 크기입니다. 예에서 빨간색 Container에 크기를 설정하지 않았으므로 화면 전체를 차지하고, Stack이 차지하는 크기도 빨간색 Container의 크기와 같게 됩니다.
또한 Stack에 추가되는 위젯의 위치를 조정할 수 있지만 설정하지 않으면 기본으로 Left-Top이 적용됩니다.
겹쳐서 하나만 보이기 — IndexedStack
IndexedStack은 Stack처럼 위젯을 겹쳐서 배치하는 위젯입니다. 그런데 Stack은 여러 위젯이 겹쳐서 보이지만, IndexedStack은 하나만 보여 주는 위젯입니다. 이때 화면에 출력할 위젯은 index 속성으로 설정합니다. 다음 코드에서는 IndexedStack에 위젯을 3개 추가하고 index 속성값을 1로 설정하여 녹색 Container만 출력한 예입니다.
IndexedStack(
index: 1,
children: [
Container(
color: Colors.red,
),
Container(
width: 300,
height: 300,
color: Colors.green,
),
Container(
width: 150,
height: 150,
color: Colors.yellow,
)
],
),
책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.
'flutter' 카테고리의 다른 글
플러터 - ListView (0) | 2023.03.13 |
---|---|
플러터 - TextField (0) | 2023.03.13 |
플러터 - Text Widget (0) | 2023.03.13 |
플러터 - StatefulWidget (0) | 2023.03.13 |
플러터 - mixin (0) | 2023.03.13 |