Widget 이란?
플러터에서 위젯은 UI를 구성하는 모든 기본 단위요소
View라고 생각하면 편하다.
플러터에서는 뷰를 정의할때 내부 속성값으로 쓰는 margin이나 padding 등과 같이 눈에 보이지 않는 요소들도 Widget이라 부른다.
레고 부품이라고 생각하고 위젯끼리 붙여서 화면을 만들고 이 화면도 위젯이라고 할 수 잇다.
Widget 종류
플러터 앱의 위젯은 두 가지로 구분한다.
stateless
상태가 없는 위젯, 화면상에서는 존재하지만 실시간 데이터를 저장하지 않고 어떠한 상태도 가지지 않는 위젯.
어플의 로고가 띄워져 있는 경우 이는 클릭을 한다던가의 액션으로 상태를 변화시키지 않는 단순한 위젯이다.
정적인 위젯이라고 생각하면 된다.
stateful
상태가 있는 위젯, 사용자의 이벤트나 데이터에 따라 값이 바뀌는 위젯.
계산기와 같이 숫자가 변화하는 뷰를 만들 경우 이는 앱이 위젯의 상태를 보다가 위젯이 특정 상태가 될 때
알맞은 처리를 수행해야 한다.
동적인 위젯이라고 생각하면 된다.
Widget 사용예제
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
var switchValue = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'jutole',
theme: ThemeData(
primarySwatch: Colors.indigo,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
darkTheme: ThemeData.light(),
home: Scaffold(
body: Center(
child: Switch(
value: switchValue,
onChanged: (value){
switchValue = value;
},
),
),
),
);
}
}
스위칭버튼이있고 누르면 스위칭되면서 변하는 화면을 만들려고 했다.
하지만 눌러도 반응이 없다. 그 이유는 정적인 위젯인 StatelessWidget 클래스를 상속 받았기 때문이다.
이를 해결하기 위해서는 StatefulWidget 클래스를 상속받고 사용해야 한다.
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyApp();
}
}
class _MyApp extends State<MyApp> {
var switchValue = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'jutole',
theme: ThemeData(
primarySwatch: Colors.indigo,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
darkTheme: ThemeData.light(),
home: Scaffold(
body: Center(
child: Switch(
value: switchValue,
onChanged: (value){
setState(() {
switchValue = value;
});
},
),
),
),
);
}
}
StatefulWidget을 적용한 코드이다. 스위칭하면 화면이 바뀐다.
StatefulWidget의 경우 혼자서 화면을 출력 할 수 없고 State라는 클래스가 필요하다.
그래서 State클래스를 상속받는 _MyApp클래스를 만들어 위에서 만들어놓은 위젯을 담는다.
그리고 상속받은 MyApp에 필수구현해야할 메서드를 재정의하고 _MyApp클래스를 호출한다.
이제 이렇게 되면 MyApp클래스가 현재 화면을 주시하고 상태가 변경되면 이를 감지하고 _MyApp클래스가 화면을 갱신한다.
화면을 갱신하기 위해 setStaet() 함수를 이용했다.
Widget의 생명주기
StatelessWidget 의 경우는 정적이기 때문에 생명주기가 없다. 그러므로 화면이 넘어갈 경우 모든 로직이 종료된다.
StatefulWidget 의 경우에는 10단계로 구분하는 생명주기가 존재한다.
1. 상태를 생성하는 createState()
StatefulWidget 클래스를 상속받는 클래스는 반드시 createState()함수를 호출해야 한다.
이 함수는 다른 생명주기 함수들이 포함된 State클래스를 반환한다. 위젯의 상태를 생성하는 함수이다.
위의 예제에서도 사용하였다.
2. mounted == true
createState() 함수가 호출되어 상태가 생성되면 바로 mounted 속성이 true로 변경된다.
mounted 속성 true가 의미하는 것은 위젯을 제어할 수 있는 buildContext 클래스에 접근할 수 있다는 의미이다.
buildContext가 활성화 되어야만 우리가 Switch 위젯을 만들때 사용했었던 setStaet() 함수를 이용할 수 있다.
3. initeState()
이 함수는 위젯을 초기화할 때 한 번만 호출된다. 그래서 주로 데이터 목록을 만들거나 처음 필요한 데이터를 주고받을 때 호출한다.
4. didChangeDependencies()
이 함수는 데이터에 의존하는 위젯이라면 화면에 표시하기 전에 꼭 호출해야한다.
주로 상속받은 위젯을 사용할 때 상속받는자가 변경되면 호출한다.
5. build()
이 함수는 widget을 반환한다. 즉 위젯을 화면에 띄우는 함수이다.
위에서 앱을 만들 때도 재정의 했다.
6. didUpdateWidget()
부모 위젯이나 데이터가 변경되어 위젯을 갱신해야 할 때 호출한다.
만약 inistState()에서 특정 이벤트에 의해 위젯이 변경되면 didUpdateWidget()함수를 호출해 위젯을 갱신할 수 있다.
7. setState()
데이터가 변경되었다는 것을 알려주고 변경된 데이터를 이용해 화면의 UI를 변경할 수 있도록 한다.
가장 많이 사용된다.
8. deactivate()
State 객체가 플러터의 구성 트리로부터 제거될 때 호출된다.
하지만 해당 메모리까지는 지워지지 않아서 dispose() 함수를 호출하기 전까지 State객체를 재사용할 수 있다.
9. dispose()
deactivate()에 이어 State 객체를 영구적으로 소멸할 때 호출된다.
즉 이 함수를 사용하면 해당 위젯을 종료한다는 뜻이다.
10. mounted == false
State 객체가 소멸하면 마지막으로 mounted 속성이 false로 되면서 생명주기가 끝난다.
'Flutter > 기본' 카테고리의 다른 글
Flutter) TextFormField 숫자만 입력받기. (1) | 2022.09.29 |
---|---|
Flutter) Container에 BoxDecoration 사용하기 (0) | 2022.08.10 |
Flutter) RichText 위젯 (0) | 2022.08.09 |
Flutter) google_maps_flutter 사용해보기 (0) | 2022.08.08 |
WidgetsFlutterBinding.ensureInitialized(); (0) | 2022.07.27 |