이 글에서는 flutter의 statefulwidget에 대해 알아본다.
지금까지는 flutter에 대해 알아보면서 StatelessWidget만을 사용해왔다.
StatelessWidget은 상태가 없는 위젯으로 한 번 화면에 띄워지면 다시 바뀌지 않는 위젯이다.
(즉, 단 한번만 build가 된다. 절대로 재실행되지 않는다.)
이와는 반대로 StatefulWidget은 상태를 가진다.
앱이 실행되면서 변수 값 등이 바뀌면서 상태가 바뀌면 StatefulWidget은 그에 맞게 변화한다.
상태가 바뀌어 있는 상태를 dirty 상태라고 하고 이 상태가 되면 StatefulWidget은 build()를 다시 실행한다.
그러고 나면 clean 상태가 된다.
이 상태에서 widget이 변경되거나, state가 변경되면 다시 dirty 상태로 돌아간다.
아래 그림은 StatefulWidget의 생명 주기이다.
지금부터는 StatefulWidget을 활용한 앱을 제작해본다.
StatefulWidget을 활용하여 만들 앱은 기본적인 카운터이다.
Down 버튼은 숫자를 1씩 줄어들게 하고, Up 버튼은 1씩 늘어나게 한다.
Reset은 숫자를 0으로 초기화한다.
전체 코드는 다음과 같다.
import 'package:flutter/material.dart';
void main() {
runApp(CounterPage());
}
class CounterPage extends StatefulWidget{
CounterPage({Key? key}): super(key: key);
@override
State<CounterPage> createState()=> _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int _count=0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$_count",
style: const TextStyle(
fontSize: 30.0
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
OutlinedButton(
onPressed: (){
setState(() {
_count--;
});
},
child: const Text(
"Down"
),
),
OutlinedButton(
onPressed: (){
setState(() {
_count = 0;
});
},
child: const Text(
"Reset"
),
),
OutlinedButton(
onPressed: (){
setState(() {
_count++;
});
},
child: const Text(
"Up"
), //Text
), //OutlinedButton
],
), //Row
],
), //Column
), //Center
), //Scaffold
); //MaterialApp
}
}
지금부터 하나하나 뜯어보도록 하자.
1. StatefulWidget
class CounterPage extends StatefulWidget{
CounterPage({Key? key}): super(key: key);
@override
State<CounterPage> createState()=> _CounterPageState();
}
StatefulWidget을 상속 받는 CounterPage class를 생성한다.
CounterPage({Key? key})는 생성자이다.
super를 통해 StatefulWidget의 생성자를 불러온다.
2. State
그 다음으로는 StatefulWidget의 상태를 생성해준다.
createState()를 사용해 상태를 생성해준다.
_CounterPageState 클래스가 이 상태를 상속받는다.
class _CounterPageState extends State<CounterPage> {
int _count=0;
@override
Widget build(BuildContext context) {
return MaterialApp(
...
_CounterPageState는 앞서 생성안 CounterPage의 상태를 상속받는다.
_count는 카운트한 값을 저장하는 용도이다.
Widget build 메서드는 StatelessWidget과 동일하다.
3. 화면 구성하기
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"$_count",
style: const TextStyle(
fontSize: 30.0
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
OutlinedButton(
onPressed: (){
setState(() {
_count--;
});
},
child: const Text(
"Down"
),
),
OutlinedButton(
onPressed: (){
setState(() {
_count = 0;
});
},
child: const Text(
"Reset"
),
),
OutlinedButton(
onPressed: (){
setState(() {
_count++;
});
},
child: const Text(
"Up"
),
),
],
),
],
),
),
),
);
}
굉장히 코드가 길어 보이지만 텍스트 하나와 버튼 3개로 구성된 간단한 코드이다.
화면 구성을 위한 위젯 트리는 다음과 같다.
우선 Center 위젯을 통해 모든 위젯이 중앙에 위치할 수 있도록 만든다.
그 다음 Column을 통해 Text 위젯과 Row 위젯이 행 방향으로 정렬되도록 한다.
Row 안에는 down, up, reset 버튼이 열 방향으로 위치할 수 있도록 한다.
OutlinedButton(
onPressed: (){
setState(() {
_count = 0;
});
},
child: const Text(
"Reset"
),
),
버튼 안의 onPressed 파라미터 안에 setState()가 들어가 있는 것을 볼 수 있다.
setState 안에 실행할 코드를 넣으면 버튼을 눌렀을 때 코드를 실행하고, 화면을 업데이트한다.
만약 안에 setState가 없으면 아무리 버튼을 눌러도 화면이 업데이트 되지 않는다.
'플러터 (flutter)' 카테고리의 다른 글
Flutter - 내비게이션 바 (NavigationBar) (0) | 2023.06.26 |
---|---|
Flutter PageView 위젯 (0) | 2023.06.24 |
Flutter WebView 위젯 (0) | 2023.06.23 |
Flutter와 위젯(Widget) (2) (0) | 2023.06.23 |
Flutter와 위젯(Widget) (0) | 2023.06.21 |