위젯이란
Everything is a Widget
모든 것은 위젯이다.
- 위젯이란 현재 주어진 상태를 기반으로 어떤 UI를 구현할지 정의 : 플러터 화면의 모든 것들은 위젯이라고 봐도 무방
- 위젯의 상태가 변경이 되면 변경 상태에 맞게 다시 UI를 그린다 : 변경 없는 위젯은 그대로 두고 변경이 있는 위젯들만 새로 그림
- 위젯은 다른 위젯을 포함할 수 있으며 부모와 자식 관계로 구성된다 : 트리 구조
child를 가지는 위젯
- 자식을 하나만 가지는 위젯
1) Container
- 자식을 담는 컨테이너 역할
- 배경 , 너비 , 높이 , 테두리 등 지정 가능
2) GesturDetector
- 위젯에 제스처 (터치) 기능을 제공
- 탭 , 드래그 , 더블 클릭 같은 기능 제공
- 터치 시 함수 실행
3) SizeBox
- 높이와 너비 지정
- Container와 다르게 디자인 요소는 하나도 없음
- const 지정 가능하니까 퍼포먼스 좋긴함
children를 가지는 위젯
- 자식을 여러 개 가지는 위젯
1) Column
- 모든 위젯을 세로로 배치
- 세로로 무제한 , 가로로 부모 너비 만큼
2) Row
- 모든 위젯을 가로로 배치
- 가로로 무제한 , 세로는 부모 길이 만큼
3) ListView
- 리스트 구현
- 입력된 위젯들이 화면을 벗어나는 경우 스크롤 가능
텍스트 관련 위젯
- 글자를 랜더링하는 위젯
- 글꼴, 색상 , 크기 등등을 TextStyle을 통해서 변경 가능
child: Text(
'텍스트 위젯',
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.w700,
color: Colors.blue,
),
),
제스처 관련 위젯
- 제스처 : 키보드 입력 제외한 모든 입력을 뜻함
- 한 번 탭 , 두 번 탭, 길게 누르기, 드래그 등등
- GestureDetector 위젯은 모든 제스처를 매개변수로 제공하여 하위 위젯에 동작 감지가 되면 콜백 함수를 호출한다
1) Button
- 기본 제공 버튼임
- 버튼 누르면 색이 변경되는 리플 효과 지원
- 스타일은 styleForm()을 통해 지정가능
TextButton(
onPressed: () {},
style: TextButton.styleFrom(foregroundColor: Colors.red),
child: Text('텍스트 버튼'),
),
OutlinedButton(
onPressed: () {},
style: OutlinedButton.styleFrom(foregroundColor: Colors.orange),
child: Text('아웃라인드 버튼'),
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(backgroundColor: Colors.yellow),
child: Text('엘레베이티드 버튼'),
),
2) IconButton
- 플러터에서 제공하는 기본 아이콘을 토대로 버튼으로 생성
IconButton(
onPressed: () {},
iconSize: 200,
icon: Icon(Icons.home),
),
3) GestureDetector
- 손가락으로 하는 여러 입력들을 인지하는 위젯
- 하위 위젯이 동작 감지시 설정된 콜백 함수를 호출
- 탭 한 번 , 탭 두 번 , 길게 탭 ,드래그, 확대, 축소 등등
GestureDetector(
onTap: (){
print('on tap');
},
onDoubleTap: (){
print('on double tap');
},
onLongPress: (){
print('on long tap');
},
child:Container(
decoration: BoxDecoration(
color: Colors.orange,
),
width: 100.0,
height: 100.0,
),
)
4) FloatingActionButton
- 화면에 둥둥 떠다니는 버튼
- Scaffold에 보통 사용
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: HomeScreen(),
floatingActionButton: FloatingActionButton(
onPressed: (){},
child: Text('클릭'),
),
),
)
);
}
디자인 관련 위젯
1) Container
- 다른 위젯을 담는데 사용
- 너비, 높이, 테두리 , 배경색 등 설정
Container(
decoration: BoxDecoration(
color: Colors.orange,
border: Border.all(
width: 12.0,
color: Colors.deepPurple,
),
borderRadius: BorderRadius.circular(16.0),
),
height: 100.0,
width: 200.0,
),
2) SizeBox
- 일정 크기 공간을 공백으로 두는 위젯
- 디자인 요소 일체 없음
- const 생성자 사용하여 퍼포먼스 이점 굳
- 보통 위젯들 사이에 공백을 넣기 위해 사용
SizedBox(
height: 200,
width: 200,
child: Container(
color: Colors.red,
),
)
3) Padding
- child 위젯이 여백 제공
- EdgeInsets 사용하여 상위 위젯과 하위 위젯 사이에 여백을 둘 수 있음
- 상위 위젯인 Container와 하위 위젯인 Container 사이에 여백이 상하좌우 16씩 생김
Container(
color: Colors.blue,
child: Padding(
padding: EdgeInsets.all(16.0),
child: Container(
color: Colors.red,
width: 50,
height: 50,
),
4) Margin
- 위젯의 바깥 간격 추가하는 기능
- 속성으로 지정해줌 : 위젯이 없음
- 바깥에서 부터 여백 생기는 거라 쪼그라드는 느낌
Container(
color: Colors.black,
child: Container(
color: Colors.blue,
margin: EdgeInsets.all(16.0),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Container(
color: Colors.red,
width: 50,
height: 50,
),
),
),
)
5) SafeArea
- 위젯을 가리지 않고 안전한 화면에서 위젯 그리기가 가능해짐
- 적용 전에는 노치까지 화면을 차지하지만 적용 후에는 노치 제외한 화면에 위젯을 그림
SafeArea(
top: true,
child: Container(
color: Colors.blue,
height: 300,
width: 300,
));
배치 관련 위젯
1) Row
- 가로로 위젯을 배치
- 여러 개의 하위 위젯들을 받을 수 있음
- 가로가 주축(main axis) , 세로가 반대축 (cross zxis) : 축을 활용하여 위젯을 다양하게 배치
SizedBox(
// 높이 최대
height: double.infinity,
child: Row(
// 주축 정렬
mainAxisAlignment: MainAxisAlignment.start,
// 반대축
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 50,
width: 50,
color: Colors.red,
),
const SizedBox(width: 12.0,),
Container(
height: 50,
width: 50,
color: Colors.green,
),
const SizedBox(width: 12.0,),
Container(
height: 50,
width: 50,
color: Colors.blue,
),
],
),
);
그 외 Row 주축 스타일 (main axis)
Row 반대축 스타일 (cross axis)
2) Column
- 세로로 위젯을 배치
- 여러 개의 하위 위젯들을 받을 수 있음
- 세로가 주축(main axis) , 가로가 반대축 (cross zxis) : 축을 활용하여 위젯을 다양하게 배치
SafeArea(
top: true,
child: SizedBox(
// 높이 최대
width: double.infinity,
child: Column(
// 반대축 정렬
mainAxisAlignment: MainAxisAlignment.start,
// 주축
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 50,
width: 50,
color: Colors.red,
),
const SizedBox(width: 12.0,),
Container(
height: 50,
width: 50,
color: Colors.green,
),
const SizedBox(width: 12.0,),
Container(
height: 50,
width: 50,
color: Colors.blue,
),
],
),
),
);
그 외 주축 스타일 (main axis)
그 외 반대축 정렬 (cross axis)
3) Flexible
- Row나 Column에 사용
- 부모 위젯에서 얼마만큼의 비율로 공간을 차지할지 지정
Column(
children: [
Flexible(
flex: 3,
child: Container(
color: Colors.blue,
),
),
Flexible(
flex: 1,
child: Container(
color: Colors.red,
),
),
],
);
4) Expanded
- Flexible위젯을 상속하는 위젯
FlexFit.tight : 남은 공간을 모두 차지 = Expanded는 해당 속성을 가지고 있는 Flexible을 상속한 위젯
- Row나 Column에서 사용되며 부모 위젯의 남아 있는 공간을 최대한으로 차지
- flex 속성으로 비율 조절 가능
Column(
children: [
Expanded(
child: Container(
color: Colors.blue,
),
),
Expanded(
child: Container(
color: Colors.red,
),
),
],
);
5) Stack
- 위젯을 겹쳐서 쌓는 기능
- children에 위치한 순서대로 겹침
Stack(
children: [
Container(
height: 300.0,
width: 300.0,
color: Colors.red,
),
Container(
height: 250.0,
width: 250.0,
color: Colors.yellow,
),
Container(
height: 200.0,
width: 200.0,
color: Colors.blue,
),
],
),
참고
“이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.”
https://jacobko.info/flutter/flutter-01/
https://arzerin.com/2019/11/20/flutter-row/
https://arzerin.com/2019/11/20/flutter-column/
'프로그래밍 > 플러터' 카테고리의 다른 글
BuildContext란? (0) | 2024.02.23 |
---|---|
스플래시 스크린 앱 작성 (0) | 2024.02.21 |
플러터 입문하기 (0) | 2024.02.19 |
Expand 위젯 에러 : RenderFlex children have non-zero flex but incoming height constraints are unbounded. (0) | 2024.02.19 |
Unable to boot the Simulator (0) | 2024.02.19 |
하고 싶은 걸 하고 되고 싶은 사람이 되자!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!