목차
배치 위젯(Arrange Widget)
배치 위젯은 하위 위젯을 가로나 세로로 배치하거나 위젯들 간의 위나 아래로 겹칠 때 사용한다.
Row 위젯
Row 위젯은 하위 위젯을 가로로 배치하는 데 사용한다.
Row와 Coulmn에는 주축(Main Axis)와 반대축(Cross Axis)라는 개념이 존재하는데,
Row는 가로가 주축, 세로가 반대축이 된다.
Column의 경우엔 가로가 반대축, 세로가 주축이 된다.
Row 위젯으로 작성한 전체 코드
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SizedBox(
height: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 75.0,
width: 75.0,
color: Colors.red,
),
const SizedBox(width: 12.0),
Container(
height: 75.0,
width: 75.0,
color: Colors.green,
),
const SizedBox(width: 12.0),
Container(
height: 75.0,
width: 75.0,
color: Colors.yellow,
),
],
),
),
),
);
}
}
위의 코드에서 해당 부분은 여백을 넣기 위해 들어간다. Container 사이에 여백을 두어 구분하기 쉽게 만들었다.
const SizedBox(width: 12.0),
해당 코드에서 주축과 반대축의 정렬을 지정할 수 있다.
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
위의 코드 값에서 아래의 옵션을 설정할 수 있다.
옵션별 사진을 아래에서 살펴보자.
옵션 | 설명 |
MainAxisAlignment.start | 시작에 정렬 |
MainAxisAlignment.center | 중앙에 정렬 |
MainAxisAlignment.end | 끝에 정렬 |
MainAxisAlignment.spaceBetween | 위젯 간의 간격을 균등하게 정렬 |
MainAxisAlignment.spaceAround | 위젯의 간격을 균등하게 하고, 왼쪽 끝과 오른쪽 끝을 위젯 사이거리의 반만큼 배정해 정렬 |
MainAxisAlignment.spaceEvenly | 위젯의 간격을 균등하게 배치하고 왼쪽 끝 간격과 오른쪽 끝 간격 또한 균등하게 배치 |
CrossAxisAlignment.start | 시작에 정렬 |
CrossAxisAlignment.center | 중앙에 정렬 |
CrossAxisAlignment.end | 끝에 정렬 |
CrossAxisAlignment.stretch | 반대축을 최대한 늘려서 정렬 |
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
위의 코드에서 center 부분을 수정하고
start, center, end를 조합을 해 배치를 할 수 있다.
start + center / center + center / end + center
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
아래의 옵션은 가로(주축)에만 사용이 가능하다.
MainAxisAlignment. 부분에 옵션 값을 넣어주면 된다.
spaceBetween / spaceAround / spaceEvenly
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
Column 위젯
Column 위젯은 Row 위젯과 같은 매개변수를 사용하지만, 주축과 반대축이 반대로 있다.
child: Row라고 되어 있던 부분을 Column으로 바꾸면 Column 위젯을 사용할 수 있다.
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
)
또한 width: double.infinity 설정을 해주어야 화면의 가로를 모두 사용할 수 있으므로 설정을 해줘야 한다.
width: double.infinity,
height: double.infinity,
옵션 | 설명 |
MainAxisAlignment.start | 시작에 정렬 |
MainAxisAlignment.center | 중앙에 정렬 |
MainAxisAlignment.end | 끝에 정렬 |
MainAxisAlignment.spaceBetween | 위젯 간의 간격을 균등하게 정렬 |
MainAxisAlignment.spaceAround | 위젯의 간격을 균등하게 하고, 왼쪽 끝과 오른쪽 끝을 위젯 사이거리의 반만큼 배정해 정렬 |
MainAxisAlignment.spaceEvenly | 위젯의 간격을 균등하게 배치하고 왼쪽 끝 간격과 오른쪽 끝 간격 또한 균등하게 배치 |
CrossAxisAlignment.start | 시작에 정렬 |
CrossAxisAlignment.center | 중앙에 정렬 |
CrossAxisAlignment.end | 끝에 정렬 |
CrossAxisAlignment.stretch | 반대축을 최대한 늘려서 정렬 |
아래의 코드 부분을 위의 표를 참고해 작성해보자.
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
위의 코드에서 center 부분을 수정하고
start, center, end를 조합을 해 배치를 할 수 있다.
start + center / center + center / end + center
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
아래의 옵션은 세로(반대축)에만 사용이 가능하다.
spaceBetween / spaceAround / spaceEvenly
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
Flexible 위젯
Flexible 위젯은 Row 위젯과 Column 위젯에 함께 사용하는 위젯으로, child가 Row와 Column에서의 여유 공간을 활용할 수 있다.
위에서 말한 바와 같이 Flexible 위젯은 Row와 Column 안에서 사용해야 한다.
여유 공간을 얼마나 차지할 지 child 별로 비율을 지정할 수 있다.
Column 1:3:1 / Row 1:3:1
또한 Flex는 Expanded와 함께 사용될 수 있으며 비율을 지정할 수 있다.
flexible을 사용하면 다른 위젯들과 비율을 차지 한 다음에, 해당 위젯의 크기만큼만 차지하고 남는 공간은 사용하지 않고 버린다. flexible은 잘 사용하지 않는다.
Expanded(
flex: 1,
child: Container(
color: Colors.red,
width: 50,
height: 50,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
width: 50,
height: 50,
),
),
FlextFit.tight
강제적으로 사용할 수 있는 만큼 최대한 늘리기
children: [
Container(
width: 50,
height: 100,
color: Colors.red,
),
Flexible(
fit: FlexFit.tight,
child: Container(
height: 100,
color: Colors.green,
),
),
Container(
width: 150,
height: 100,
color: Colors.yellow,
),
],
FlextFit.loose
차지해야할 공간 만큼만, 필요한 공간만 차지하기
children: [
Container(
width: 50,
height: 100,
color: Colors.red,
),
Flexible(
fit: FlexFit.loose,
child: Container(
height: 100,
color: Colors.green,
child: Text('필요한 사이즈에 맞게 줄어듭니다')),
),
Container(
width: 50,
height: 100,
color: Colors.yellow,
),
],
Expanded 위젯
Expanded 위젯은 Flexible 위젯을 상속하는 위젯으로, Row와 Column 위젯과 함께 쓰이며 해당 위제세에서 남는 여유 공간을 최대한 차지한다.
위에서 말한 바와 같이 Expanded 위젯은 Row와 Column 안에서 사용해야 한다.
Flexible과 동알하게 남는 공간에 대한 비중을 설정할 수 있으나, Row와 Column의 Child가 화면을 가득 채우도록 한다는 점이 다르다.
child: Column(
children: [
Expanded(
child: Container(
color: Colors.red,
)),
Expanded(
child: Container(
color: Colors.green,
)),
Expanded(
child: Container(
color: Colors.yellow,
)),
],
),
Stack 위젯
Stack 위젯은 위젯들을 여러 개 서로 겹치게 배치할 때 사용하는 기능이다.
Stack 위젯을 사용하면 위젯 위에 올라간 듯한 효과를 줄 수 있다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Stack(
children: [
Container(
width: 400,
height: 400,
color: Colors.pinkAccent,
),
Container(
width: 350,
height: 350,
color: Colors.purple,
),
Container(
width: 300,
height: 300,
color: Colors.blue,
),
Container(
width: 250,
height: 250,
color: Colors.green,
),
Container(
width: 200,
height: 200,
color: Colors.yellow,
),
Container(
width: 150,
height: 150,
color: Colors.orange,
),
Container(
width: 100,
height: 100,
color: Colors.red,
),
],
),
),
),
);
}
}
배치 위젯 연습하기 (ex 사람 얼굴 만들기)
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
bottom: false,
child: Container(
width: MediaQuery.of(context).size.width,
color: Colors.black,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: Container(
width: 50,
height: 50,
color: Colors.red,
),
),
Expanded(
child: Container(
width: 50,
height: 50,
color: Colors.blue,
),
),
Expanded(
child: Container(
width: 50,
height: 50,
color: Colors.amber,
),
),
Expanded(
child: Container(
width: 50,
height: 50,
color: Colors.green,
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
width: 50,
height: 50,
color: Colors.white,
),
Container(
width: 50,
height: 50,
color: Colors.white,
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 50,
height: 50,
color: Colors.red,
),
Container(
width: 50,
height: 50,
color: Colors.blue,
),
Container(
width: 50,
height: 50,
color: Colors.amber,
),
Container(
width: 50,
height: 50,
color: Colors.green,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
width: 50,
height: 50,
color: Colors.purple,
),
],
),
],
),
),
),
);
}
}
댓글