老孟導讀:此篇文章是生命週期相關文章的番外篇,在查看源碼的過程當中發現了這一有趣的問題,歡迎你們一塊兒探討。html
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.htmlgit
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(); ... }
刪除了一些代碼,保留了重點代碼。ide
試想一下,若是 build 方法放在 StatefulWidget 中,則 AnimatedWidget 中的 build 方法須要帶一個 State 參數,以下:性能
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 是內部實現,並不須要開放給外部(開發者),外部也不須要知道 AnimatedState 的內部實現。動畫
假設 build 方法在 StatefulWidget 中,StatefulWidget 的子類寫法以下:ui
class MyWidget extends StatefulWidget { final Color color; @override Widget build(BuildContext context, MyWidgetState state) { print('${this.color}'); return Container(); } }
此時的 this 指向的是 MyWidget 的實例,而後父組件改變顏色,從新構建 MyWidget 組件,前一個 MyWidget 的實例中的 this 依然指向前一個 MyWidget 的實例,顏色並未發生變化。this
若是 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(); } }
一樣,父組件改變顏色,從新構建 MyWidget 組件,此時框架更新了 State 對象的 widget 屬性的引用,新的 MyWidget 實例和 $ {widget.color} 將顯示綠色。
有狀態的組件包含StatefulWidget 和 State,當有狀態組件的配置發生更改時,StatefulWidget 將會被丟棄並重建,而 State 不會重建,框架會更新 State 對象中 widget 的引用,這極大的減輕了系統重建有狀態組件的工做。
此方式對動畫來講極爲重要,因爲 State 不會被重建,保留了前面的狀態,不斷的根據前一個狀態計算下一個狀態並重建其widget,達到動畫的效果。
老孟Flutter博客(330個控件用法+實戰入門系列文章):http://laomengit.com
歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】: