接下來三天會提到跟狀態管理有關的議題
由於React跟Flutter的核心思想都是State
所以怎麼管理或傳遞這個State
就變得非常重要
然後就會衍生出一堆作法/流派(很煩= =)
總之先從簡單的開始吧
今天介紹的是Flutter Widgets 101中
重要性僅次於stless跟stful的InheritedWidget
因為Flutter的特性
UI樹是一層包一層
若底層的widget若想取得上層的state會很麻煩(要一路傳下去)
所以Flutter提供了InheritedWidget
讓底層widget低等下人可以方便取得上層的state
大概像我們以前, 如果有資料大家都要用的話
會用Singleton或是直接寫在AppDelegate XD☘️☘️☘️
InheritedWidget這邊提到的繼承
是Widget樹上的繼承
並不是我們以前物件導向常提到的Class的繼承
而且InheritedWidget是讓
人家繼承不是去
繼承人家
情境是我們有個神之物件(GodWidget)
若他的心情變了
天空(SkyWidget)的天氣也變了
(是不是跟你的老闆很像 他不爽了我們就要大地震?)
widget結構如下
實作流程如下(詳見註解)
class GodWidget extends InheritedWidget {
//官方建議要用final, 這樣你就不能隨便去改它
final Weather todayWeather;
//因為是要放在上層, 所以建構子一定要有child, 跟你要共享的資料
GodWidget(this.todayWeather, Widget cho) : super(child: cho);
//of方法是一個慣例, 代表這個widget是開放給大家取用, 官方建議這麼寫
static GodWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<GodWidget>();
//如果用getElementXXX太長的背不起來, 繼承的widget就不會call didChangeDependencies
//return context.getElementForInheritedWidgetOfExactType<GodWidget>().widget;
}
//此widget更新後是否通知其他widget
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return true;
}
}
class LessonPageInheritedWidget extends StatefulWidget {
@override
_LessonPageInheritedWidgetState createState() => _LessonPageInheritedWidgetState();
}
class _LessonPageInheritedWidgetState extends State<LessonPageInheritedWidget> {
String currentMood;
Weather currentWeather;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("第十八堂課"),
actions: <Widget>[
DropdownButton(
hint: Text("心情?"),
value: null,
items: [
DropdownMenuItem(child: Text("大晴天"), value: Weather.sunny),
DropdownMenuItem(child: Text("下雨天"), value: Weather.rainy),
DropdownMenuItem(child: Text("做颱風"), value: Weather.typhoon),
DropdownMenuItem(child: Text("暴風雪"), value: Weather.blizzard),
],
onChanged: (v){
setState(() {
currentWeather = v;
});
}
)
],
),
backgroundColor: Colors.red,
body: GodWidget(currentWeather, SkyWidget())
);
}
}
class SkyWidget extends StatefulWidget {
@override
_SkyWidgetState createState() => _SkyWidgetState();
}
class _SkyWidgetState extends State<SkyWidget> {
@override
Widget build(BuildContext context) {
Widget widgetIcon(IconData ico){
return Container(
alignment: Alignment.center,
color: Colors.blue,
child: Icon(ico, color: Colors.white, size: 100),
);
}
switch (GodWidget.of(context).todayWeather) {
case Weather.sunny:
return widgetIcon(IcoFontIcons.sunny);
case Weather.rainy:
return widgetIcon(IcoFontIcons.rainy);
case Weather.typhoon:
return widgetIcon(IcoFontIcons.wind);
case Weather.blizzard:
return widgetIcon(IcoFontIcons.snow);
default:
return Container(child: null, color: Colors.red);
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("天意啊~~~");
}
}
PS. 不要直接去改InheritedWidget的state(不可對神不敬)
(這位哥的表情真的有戲ww)
下集預告:Provider
最後提供一下github.com/mark33699/IDLF