일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 앱
- Navigation
- LifeCycle
- Dialog
- 테스트
- drift
- scroll
- 계측
- activity
- android
- Button
- textview
- CustomScrollView
- Coroutines
- TEST
- Kotlin
- appbar
- intent
- DART
- binding
- livedata
- 앱바
- Compose
- textfield
- Flutter
- data
- tabbar
- viewmodel
- ScrollView
- 안드로이드
- Today
- Total
Study Record
[Flutter] StatelessWidget / StatefulWidget 생명 주기 본문
✍ 클래스 생성 단축키
- stful : StatefulWidget 생성 단축키
- stless : StatelessWidget 생성 단축키
✍ StatelesssWidget
상태를 관리할 수 없는 위젯이다.
- Constructor 로 생성된 후 바로 build 함수가 실행된다.
- 변경이 필요하면 새로운 위젯을 만든다. (색 변경 등)
- 하나의 StatelessWidget은 라이프사이클동안 단 한 번만 build 함수를 실행한다.
※ 생명 주기
아래의 코드와 같이 StatelessWidget 을 상속받으면 StatelessWidget 을 생성할 수 있다. build() 함수의 return 값으로 생성하고자 하는 위젯을 리턴하면 된다.
class HomeScreen extends StatelessWidget{
String imgPath;
HomeScreen({required this.imgPath});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Image.asset(imgPath)
)
);
}
}
/**
* main 함수에서 StatelessWidget 사용 예시
*/
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: HomeScreen(imgPath: "asset/img/free_hart_img.png"),
),
);
}
예시로 만든 HomeScreen 클래스(위젯)은 한 번 생성되면 build() 함수가 생성될 당시 한 번만 실행되기 때문에 이미지 값(asset/img/logo.png)을 변경할 수 없다. imgPath 를 직접 변경한다고 해도 build() 를 다시 호출할 수 없기 때문에 이미지를 변경할 수 없다. 이렇듯 StatelessWidget 은 새로 값이 변경되어야 한다면 변경된 값의 새로운 위젯을 만든다.
+ Hot reload 는 빌드함수에서 리턴하는 위젯의 변경시 사용할 수 있다.
✍ StatefulWidget
상태를 관리할 수 있는 위젯이다. 위젯의 상태를 관리하는 State 클래스가 사용된다.
※ 생명 주기
기본적으로 StatefulWidget 의 생명 주기는 위의 그림과 같다. 위젯이 정상적으로 생성되면 Clean 상태까지 유지되고 위젯(StatefulWidget) 이 삭제된다고 무조건 연결된 State 가 deactivate() → dispose() 과정을 거치지는 않는다.
class StatefulTestHomeScreen extends StatefulWidget {
const StatefulTestHomeScreen({Key? key}) : super(key: key);
@override
State<StatefulTestHomeScreen> createState() => _StatefulTestHomeScreenState();
}
class _StatefulTestHomeScreenState extends State<StatefulTestHomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
...
),
),
);
}
}
StatefulWidget 가 삭제되고 State 가 deactivate() → dispose() 과정을 거치지는 않는 경우가 있는데 파라미터 값이 바뀌었을 경우이다. 예를 들어, 기존의 위젯에서 색상을 바꾸고 싶다면 새로운 위젯이 생성되는데 여기서 StatelfulWidget 이 삭제되고 새로 생성될 때 State 는 삭제되지 않고 새롭게 생성되는 StatefulWidget 에 연결된다. 과정을 그림으로 보면 다음과 같다.
연결되는 과정에서 didUpdateWidget() 가 불리고 build() 함수가 불리면서 위젯이 새로 생성된다.
StatefulWidget 을 사용하는 이유라고도 할 수 있는 State 클래스의 setState() 함수가 있는데 이 함수를 사용하면 StatefulWidget 을 삭제하지 않고 값을 바꿀 수 있다. 생명 주기의 과정은 다음과 같다.
예를 들어 "위젯 색깔 바꾸기" 버튼을 누르면 중앙에 있는 위젯의 바탕색이 바뀌는 간단한 앱이 있으면,
다음과 같이 StatefulTestHomeScreen 클래스를 작성할 수 있을 것이다.
class StatefulTestHomeScreen extends StatefulWidget {
const StatefulTestHomeScreen({Key? key}) : super(key: key);
@override
State<StatefulTestHomeScreen> createState() => _StatefulTestHomeScreenState();
}
class _StatefulTestHomeScreenState extends State<StatefulTestHomeScreen> {
Color color = Colors.orange;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 1,
child: Center(
child: CustomContainer(color: color)
),
),
Container(
margin: const EdgeInsets.all(15.0),
color: Colors.red,
child: TextButton(
onPressed: () {
setState(() {
color = (color == Colors.orange ? Colors.lightBlue : Colors.orange);
});
},
child: Container(
width: MediaQuery.of(context).size.width,
child: const Center(
child: Text(
"위젯 색깔 바꾸기",
style: TextStyle(color: Colors.white),
),
),
),
),
),
],
),
),
);
}
}
"위젯 색깔 바꾸기" 버튼을 누르면 StatefulTestHomeScreenState 의 setState() 함수가 실행되고 그때 위젯의 색상을 결정짓는 변수(color)를 변경하면 setState() → build() 함수가 불리면서 다시 CustomContainerWidget 이 바뀐 색상으로 새로 생성될 것이다.
여기서 CustomContainerWidget 을 StatefulWidget 으로도 작성할 수 있고 StatelessWidget 으로도 작성할 수 있다.
1. StatefulWidget 으로 작성된 경우
class CustomContainer extends StatefulWidget {
final Color color;
CustomContainer({required this.color, Key? key}) : super(key: key)
@override
State<CustomContainer> createState() {
return _CustomContainerState();
}
}
class _CustomContainerState extends State<CustomContainer> {
@override
Widget build(BuildContext context) {
print("_CustomContainerState build 실행");
return Container(
width: 50.0,
height: 50.0,
color: widget.color,
);
}
}
StatefulTestHomeScreenState 의 setState() 함수가 실행되고 StatefulTestHomeScreenState 의 build() 함수가 불려 다시 CustomContainer 가 새로 생성되는 경우는 파라미터 값이 바뀌었을 경우에 해당되며 과정은
StatefulTestHomeScreenState setState() → StatefulTestHomeScreenState build()
→ CustomContainer Constructor → CustomContainerState didUpdateWidget() → CustomContainerState build()
가 될 것이다. CustomContainerState build() 과정에서 위젯의 색상이 widget.color 로 되어있는데 이 의미는 현재 State 와 연결된 StatefulWidget 의 color 값을 의미한다.
따라서 StatefulTestHomeScreenState setState() 과정에서 변경한 color 값으로 StatefulTestHomeScreenState build() 에서 CustomContainer(color: color) 가 실행되면서 CustomContainer 클래스가 생성되고 연결된 CustomContainerState 의 build() 가 실행될 때 변경된 CustomContainer.color 값으로 위젯이 생성된다.
2. StatelessWidget 으로 작성된 경우
class CustomContainer extends StatelessWidget {
final Color color;
CustomContainer({required this.color, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: 50.0,
height: 50.0,
color: color,
);
}
}
마찬가지로 StatefulTestHomeScreenState 의 setState() 함수가 실행된 후 StatefulTestHomeScreenState 의 build() 함수가 불려 다시 CustomContainer 가 새로 생성된다. StatelessWidget 은 StatefulWidget 와 달리 별다른 과정이 없고 새로운 위젯이 생성된다. 따라서 과정은 다음과 같다.
StatefulTestHomeScreenState setState() → StatefulTestHomeScreenState build()
→ CustomContainer Constructor → CustomContainer build()
StatefulTestHomeScreenState setState() 과정에서 변경한 color 값으로 StatefulTestHomeScreenState build() 에서 CustomContainer(color: color) 가 실행된다.
'Flutter' 카테고리의 다른 글
[Flutter] 상태바 글자/아이콘 색상 바꾸기 (0) | 2023.01.31 |
---|---|
[Flutter] PageView Widget (0) | 2023.01.31 |
[Flutter] WebView / HTTP 접속 권한 허용 (0) | 2023.01.27 |
[Flutter] Row and Column Widget (0) | 2023.01.21 |
[Flutter] asset 추가하기 / font 사용하기 (0) | 2023.01.19 |