1.4.3 Widget源碼初識
Widget源碼在flutter/lib/src/widgets/framework.dart中,進入Widget源碼時,你會意外地發現Widget竟然如此簡潔:
Widget是一個抽象類,只有一個抽象方法createElement,返回Element對象,toStringShort返回runtimeType和key的字符串。debugFillProperties顧名思義是調試填充屬性,最后是靜態方法canUpdate。通過代碼可以看出,組件能夠更新的條件是新舊兩個Widget的runtimeType和key都相等。
abstract class Widget extends DiagnosticableTree { const Widget({ this.key }); final Key key; @protected Element createElement(); @override String toStringShort() { return key == null ? '$runtimeType' : '$runtimeType-$key'; } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense; } static bool canUpdate(Widget oldWidget, Widget newWidget) { return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; } }
Widget是一個抽象類,其最重要的當屬build抽象方法,其子類也將實現此方法。下面就來看一下Widget的兩個非常重要的子類:
StatelessWidget是不變化狀態的組件。從下面的源碼中可以看出,StatelessWidget通過StatelessElement對象來滿足父類的createElement抽象方法,并抽象出build方法返回Widget對象。再看初始項目中繼承自StatelessElement的MyApp,是不是親切許多?
StatefulWidget是有變化狀態的組件。從下面的源碼中可以看出,StatefulWidget通過StatefulElement對象來滿足父類的createElement抽象方法,并抽象出createState方法返回State對象。再看MyHomePage的實現,如果想要一個Widget擁有狀態,那么就應該繼承自StatefulWidget。其中createState方法返回一個_MyHomePageState對象,用下劃線表示是私有的,不愿讓外界訪問。現在焦點便都在_MyHomePageState這個狀態類身上。
State類中要傳入一個StatefulWidget子類的泛型,也就是說,它必須和Stateful組件聯合使用。它是一個抽象類,只有一個返回Widget對象的build抽象方法。
abstract class State<T extends StatefulWidget> extends Diagnosticable { //略... @protected Widget build(BuildContext context); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), //略...
再回看初始項目中_MyHomePageState的實現邏輯應該就會更清楚了。你應該會感覺它是一個非常好的示例程序:融合了Dart語法、自定義StatelessWidget、自定義StatefulWidget、單子組件Center、多子組件Column等,這些都是Flutter中的常用知識。當你看完本書,建議再重新審視一下初始項目,學而時習,溫故知新,也能看到自己的成長。
- Objective-C應用開發全程實錄
- Learning Bayesian Models with R
- Learning SQLite for iOS
- Android NDK Beginner’s Guide
- Node.js Design Patterns
- Nginx實戰:基于Lua語言的配置、開發與架構詳解
- Angular開發入門與實戰
- R用戶Python學習指南:數據科學方法
- Extending Unity with Editor Scripting
- Learning Splunk Web Framework
- JavaScript從入門到精通(視頻實戰版)
- Android Studio開發實戰:從零基礎到App上線 (移動開發叢書)
- Android編程權威指南(第4版)
- Python物理建模初學者指南(第2版)
- Puppet 5 Beginner's Guide(Third Edition)