老孟導讀:此篇文章是生命周期相關文章的番外篇,在查看源碼的過程中發(fā)現(xiàn)了這一有趣的問題翩瓜,歡迎大家一起探討受扳。
Flutter 中Stateful 組件的生命周期:http://laomengit.com/blog/20201227/Stateful%E7%BB%84%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html
Flutter 中與平臺相關的生命周期:http://laomengit.com/blog/20201227/%E7%9B%B8%E5%85%B3%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html
博客中還有更多精彩文章,也歡迎加入 Flutter 交流群兔跌。
靈活性
將 build 方法放在 State 中比放在 StatefulWidget 中更具靈活性勘高,比如說,AnimatedWidget 是 StatefulWidget 的子類坟桅,AnimatedWidget 是一個抽象類华望,其中有一個 Widget build(BuildContext context)
的抽象方法,此方法需要子類重寫仅乓,AnimatedWidget 源代碼如下:
abstract class AnimatedWidget extends StatefulWidget {
...
/// Override this method to build widgets that depend on the state of the
/// listenable (e.g., the current value of the animation).
@protected
Widget build(BuildContext context);
/// Subclasses typically do not override this method.
@override
_AnimatedState createState() => _AnimatedState();
...
}
刪除了一些代碼赖舟,保留了重點代碼。
試想一下夸楣,如果 build 方法放在 StatefulWidget 中宾抓,則 AnimatedWidget 中的 build 方法需要帶一個 State 參數(shù),如下:
abstract class AnimatedWidget extends StatefulWidget {
...
/// Override this method to build widgets that depend on the state of the
/// listenable (e.g., the current value of the animation).
@protected
Widget build(BuildContext context, AnimatedState state);
/// Subclasses typically do not override this method.
@override
_AnimatedState createState() => _AnimatedState();
...
}
但 AnimatedState 是內(nèi)部實現(xiàn)子漩,并不需要開放給外部(開發(fā)者),外部也不需要知道 AnimatedState 的內(nèi)部實現(xiàn)。
閉包 this 指向異常
假設 build 方法在 StatefulWidget 中石洗,StatefulWidget 的子類寫法如下:
class MyWidget extends StatefulWidget {
final Color color;
@override
Widget build(BuildContext context, MyWidgetState state) {
print('${this.color}');
return Container();
}
}
此時的 this 指向的是 MyWidget 的實例幢泼,然后父組件改變顏色,重新構(gòu)建 MyWidget 組件讲衫,前一個 MyWidget 的實例中的 this 依然指向前一個 MyWidget 的實例茴扁,顏色并未發(fā)生變化弃鸦。
如果 build 方法在 State 中,代碼如下:
class MyWidget extends StatefulWidget {
final Color color;
const MyWidget({Key key, this.color}) : super(key: key);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
@override
Widget build(BuildContext context) {
print('${widget.color}');
return Container();
}
}
同樣狞谱,父組件改變顏色载碌,重新構(gòu)建 MyWidget 組件锌畸,此時框架更新了 State 對象的 widget 屬性的引用敷硅,新的 MyWidget 實例和 $ {widget.color} 將顯示綠色疲陕。
性能
有狀態(tài)的組件包含StatefulWidget 和 State,當有狀態(tài)組件的配置發(fā)生更改時矿辽,StatefulWidget 將會被丟棄并重建,而 State 不會重建郭厌,框架會更新 State 對象中 widget 的引用袋倔,這極大的減輕了系統(tǒng)重建有狀態(tài)組件的工作。
此方式對動畫來說極為重要折柠,由于 State 不會被重建宾娜,保留了前面的狀態(tài),不斷的根據(jù)前一個狀態(tài)計算下一個狀態(tài)并重建其widget扇售,達到動畫的效果前塔。
交流
老孟Flutter博客(330個控件用法+實戰(zhàn)入門系列文章):http://laomengit.com