statelesswidget은 빌드 시 생성자가 실행된다.
이후, 필수로 override 해야하는 build()가 실행된다. build에서 반환한 위젯이 화면에 렌더링된다.
모든 위젯은 Widget 클래스를 상속하고, Widget 클래스는 불변성을 갖는다.
불변 : 클래스를 한 번 생성하고 나면, 속성을 변경할 수 없다.
위젯의 속성이 변경이 필요할 경우, 예로 생성자에 새로운 매개변수가 있을 경우.
build 시, 변경된 매개변수를 기반으로 build를 재실행해야한다.
하지만, 해당 statelesswidget은 불변으로, 재실행되지 않고, 인스턴스를 아예 새로 생성 후, 기존 인스턴스로 대체해 화면에 반영한다.
위를 해결하기 위해, 위젯 내부에서 자체적으로 build()를 재실행.
statefulWidget은 Widget 클래스와 State 클래스로 구성되고, 생명주기가 훨씬 복잡.
- StatefulWidget Constructor 실행
- createState() 실행 - 필수 override 함수로, state를 생성.
- state 생성과 함께 initState() 실행
- didChangeDependencies() 실행 - BuilderContext가 제공되고, State가 의존하는 값이 변경되면 재실행 (useEffect 느낌인가..)
- state의 상태가 dirty로 설정. build()가 재실행되어야 한다.
이 때, UI가 바뀐 상태로 재생성된다.- state의 상태가 clean로 설정. 화면에 변화가 없으면 state 유지.
- 위젯이 위젯 트리에서 사라지면, deactivate(), State가 일시적 또는 영구적으로 삭제될 때 실행.
- dispose() 위젯이 삭제될 때 실행.
- 마찬가지로 StatefulWidget 실행 후, State의 didUpdateWidget() 실행
- State가 dirty로 변경, build() 실행 후, clean 상태.
- setState() 실행
- dirty -> build() -> clean
특정 시간 이후, 일회성 또는 지속적으로 함수 실행(SetInterval 느낌..)
Timer.periodic( //SetInterval...(Timer()는 setTimeOut..)
Duration(seconds: 3), // 주기
(Timer timer){} // callback
)
StatelessWidget 내 build에 타이머 사용할 경우, 위젯 생성 때마다 Timer 재생성. (즉, build()시 마다 Timer 재생성으로, 메모리 릭 발생)
따라서, StatefulWidget 내 initState()를 통해서, 타이머 한 번만 생성.
class HomeScreen extends StatelessWidget // X
class HomeScreen extends State<HomeScreen> // O
import 'dart:async';
class HomeScreen extends State<HomeScreen> {
final PageController pageController = PageController(); // 컨트롤러 생성
@override
void initState() {
super.initState(); // 부모 initState() 실행(필수)
Timer.periodic(
Duration(seconds: 3),
(timer){
int? next = pageController.toInt();
//page getter 내에선 page값 double로 들어옴.
if(next === null){
return;
}
if(next === 4){
next = 0;
} else {
next++;
}
pageController.animateToPage(
next,
duration: Duration(milliseconds: 500),
curve: ~
)
}
)
}
@override
Widget build(BuildContext context){
return Scaffold(
body: PageView(
controller: pageController // pageController 등록
)
)
}
}
BoxFit.contain : 이미지가 잘리지 않는 선에서 최대 크게 늘림. 부모보다 작을 경우, 여백이 생김.
BoxFit.cover : 부모 위젯을 전체 덮는 선에서, 최소한의 크기로 조절. 여백은 없지만, 가로 또는 세로로 이미지가 잘릴 수 있음.
BoxFit.fill : 이미지 비율 무시하고, 부모 위젯에 이미지 비율을 맞춘다.
BoxFit.fitHeight : 이미지 비율 유지한 채, 높이만 부모 위젯가 맞춘다.
BoxFit.fitWidth : 이미지 비율 유지한 채,
BoxFit.none : 원본 비율 그대로
BoxFit.scaleDown : 원본 비율 그대로, 이미지 중앙 정렬, 부모 위젯이 이미지보다 작으면 이미지 크기를 줄여서 부모 위젯에 맞춤.
SystemChrome.setEnableSystemUIModel() : 앱의 풀스크린 모드 지정.
배터리, 시간 다 안보이게 함.
setPreferredOrientations() : 앱 실행 방향 지정
setSystemUIChangeCallback() : 시스템 UI 변경 시 콜백 실행
setSystemUIOverlayStyle() : 시스템 UI 색상 변경
State를 상속하는 모든 클래스는 해당 함수를 사용 가능.
1. StatefulWidget은 렌더링이 끝나고, 항상 Clean의 상태이다. 모든 상태는 Clean 상태에서 변경해야 한다.
2. setState()를 통해 속성을 변경한다.
3. 속성 변경 시 위젯은 Dirty 상태로 변경된다.
4. build( ) 재실행 후, State는 Clean 상태가 된다.