Flutter之旅
上QQ阅读APP看书,第一时间看更新

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中的常用知识。当你看完本书,建议再重新审视一下初始项目,学而时习,温故知新,也能看到自己的成长。