[Flutter] Widget의 종류
플러터 앱은 위젯을 기반으로 구성된다. 위젯은 앱의 UI를 구축하는 기본 단위이며 플러터 앱의 시각적인 요소를 표현한다. 따라서 플러터에서 버튼이나 텍스트, 이미지 등 UI의 모든 요소는 위젯이라고 할 수 있다.
이 위젯의 종류와 쓰임에 대해서 알아보도록 하자.
1. Text Widget
1.1 Text
화면에 텍스트를 보여주기 위해 사용하는 위젯
1
2
3
4
5
6
7
8
Text(
//style 설정
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w700,
color: Colors.blue,
),
)
2. Button Widget
2.1 TextButton
테두리가 없고 텍스트만 있는 버튼
1
2
3
4
5
6
7
8
9
TextButton(
onPressed: () {
print('click');
},
style: TextButton.styleForm(
foregroundColor: Colors.red,
child: Text('text Button'),
),
)
2.2 OutlineButton
테두리가 있는 버튼
1
2
3
4
5
6
7
8
9
OutlineButton(
onPressed: () {
print('click');
},
style: OutlineButton.styleForm(
foregroundColor: Colors.red,
),
child: Text('outline Text Button'),
)
2.3 ElevatedButton
입체감이 있는 버튼
1
2
3
4
5
6
7
8
9
ElevatedButton(
onPressed: () {
print('click');
},
style: ElevatedButton.styleForm(
backgroundColor: Colors.red,
),
child: Text('elevated Button'),
)
2.4 IconButton
이미지 적용이 가능한 버튼
1
2
3
4
5
6
7
8
9
10
IconButton(
onPressed: () {
print('click');
},
icon: Icon(
Icons.menu
),
tooltip : 'menu',
color: Colors.blue,
)
2.5 FloatingActionButton
화면 우측 하단에 나타나는 플로팅 버튼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import 'package:flutter/material.dart'
void main() {
runApp(ExFloatingButton());
}
class ExFloatingButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MateralApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: (){
print('click')
},
child: Text('floation Button'),
),
body: Container(),
),
);
}
}
3. GestureDetector Widget
제스처를 통한 입력을 인식하는 위젯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
GestureDetector(
onTap: (){
print('탭 한번');
},
onDoubleTap: () {
print('탭 두번');
},
onLongPress: () {
print('길게 탭');
},
onPanStart() {
print('수평이나 수직으로 드래그 시작');
},
onPanUpdate() {
print('수평이나 수직으로 드래그하는 동안 위치가 업데이트 될 때 실행');
},
onPanEnd() {
print('수평이나 수직으로 드래그 끝');
},
onHorizontalDragStart() {
print('수평으로 드래그 시작');
},
onHorizontalDragUpdate() {
print('수평으로 드래그하는 동안 위치가 업데이트 될 때 실행');
},
onHorizontalDragEnd() {
print('수평으로 드래그 끝');
},
onVerticalDragStart() {
print('수직으로 드래그 시작');
},
onVerticalDragUpdate() {
print('수직으로 드래그하는 동안 위치가 업데이트 될 때 실행');
},
onVerticalDragEnd() {
print('수직으로 드래그 끝');
},
onScaleStart() {
print('확대 시작');
},
onScaleUpdate() {
print('확대가 진행되는 동안 위치가 업데이트 될 때 실행');
},
onScaleEnd() {
print('확대 끝');
},
child: Container(
decoration: BoxDecoration(
Color: Colors.red,
),
width: 100.0,
height: 100.0,
),
)
4. 배치 관련 Widget
4.1 정렬 옵션
4.1.1 MainAxisAlignment - 주축정렬
옵션 | 설명 |
---|---|
start | 시작위치 정렬 |
end | 끝위치 정렬 |
center | 중앙정렬 |
spaceBetween | 위젯과 위젯의 사이가 동일하도록 배치 |
spaceEvenly | Between과 성질은 같지만 양 끝도 빈 간격으로 시작 |
spaceAround | spcaeEvenly와 같지만 양 끝이 1/2의 빈간격으로 시작 |
4.1.2 crossAxisAlignment - 반대축 정렬
옵션 | 설명 |
---|---|
start | 시작위치 정렬 |
end | 끝위치 정렬 |
center | 중앙정렬 |
stretch | 최대한으로 늘림 |
4.1.3 MainAxisSize - 주축 크기
옵션 | 설명 |
---|---|
min | 최대 크기 |
max | 최소 크기 |
4.2 Row
위젯을 가로로 배치하는 위젯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//화면 상단에 container가 가로로 나타나고
//MainAxisAligment.spaceAround 옵션으로 인해 동일 간격으로 정렬된다.
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
color: Colors.red,
width: 50.0,
height: 50.0,
),
Container(
color: Colors.orange,
width: 50.0,
height: 50.0,
),
Container(
color: Colors.yellow,
width: 50.0,
height: 50.0,
),
],
),
)
);
}
}
4.3 Column
위젯을 세로로 배치하는 위젯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//화면 상단에 container가 세로로 나타나고
//MainAxisAligment.spaceBetween 옵션으로 양끝에 공백이 없는 간격으로 정렬된다.
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
color: Colors.red,
width: 50.0,
height: 50.0,
),
Container(
color: Colors.orange,
width: 50.0,
height: 50.0,
),
Container(
color: Colors.yellow,
width: 50.0,
height: 50.0,
),
],
),
)
);
}
}
** Column과 Row를 이용해 위젯을 정중앙으로 정렬할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.red,
width: 50.0,
height: 50.0,
),
]
),
],
),
)
);
}
}
4.4 Flexible
Row 또는 Column의 children 에서 사용이 가능하며 남은 공간을 차지할 비율을 설정한다. 값을 따로 설정하지 않으면 기본 값은 1이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import 'package:flutter/material.dart';
class ExFlexible extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: [
//아래와 같이 2개의 Container를 flex 1,2 비율로 설정하면
//화면을 3등분해서 파랑, 빨강 컨테이너가 1:2비율로 나눠진다.
Flexible(
flex: 1,
child: Container(
color: Colors.blue,
),
),
Flexible(
flex: 2,
child: Container(
color: Colors.red,
),
)
],
),
),
),
);
}
}
4.5 Expanded
Flexible과 마찬가지로 Row나 Column의 children에서만 사용이 가능하고 남아있는 위젯의 공간을 최대한으로 차지한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import 'package:flutter/material.dart';
class ExExpanded extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: [
//화면을 3가지 색상으로 나눠 채운다.
Expanded(
child: Container(
color: Colors.orange,
),
),
Expanded(
child: Container(
color: Colors.yellow,
),
),
Expanded(
child: Container(
color: Colors.green,
),
)
],
),
),
),
);
}
}