再次理解一下flutter BuildContext

10 min read

理解一下flutter BuildContext 废文一篇,可以直接忽视

flutter 视图的装载过程

StatelessWidget

  • 首先它会调用StatelessWidget的 createElement 方法,并根据这个widget生成StatelesseElement对象。
  • 将这个StatelesseElement对象挂载到element树上。
  • StatelesseElement对象调用widget的build方法,并将element自身作为BuildContext传入。

StatefulWidget

  • 首先同样也是调用StatefulWidget的 createElement方法,并根据这个widget生成StatefulElement对象,并保留widget引用。
  • 将这个StatefulElement挂载到Element树上。
  • 根据widget的 createState 方法创建State。
  • StatefulElement对象调用state的build方法,并将element自身作为BuildContext传入。

所以我们在build函数中所使用的context,正是当前widget所创建的Element对象。

Widget只是配置信息

在Flutter中,Everything is Widget,我们通过构造函数嵌套Widget来编写UI界面。实际上,Widget并不是真正要显示在屏幕上的东西,只是一个配置信息,它永远是immutable的,并且可以在多处重复使用。那真正显示在屏幕上的视图树是什么呢?Element Tree!

源码

当要把这个widget装进视图树的时候,首先会去createElement,并将当前widget传给Element。

abstract class StatelessWidget extends Widget {
  const StatelessWidget({ Key key }) : super(key: key);
  @override
  StatelessElement createElement() => StatelessElement(this);
  ...

通过将widget传入StatelessElement的构造函数,StatelessElement保留了widget的引用,并且将会调用build方法

class StatelessElement extends ComponentElement {
  /// Creates an element that uses the given widget as its configuration.
  StatelessElement(StatelessWidget widget) : super(widget);

  @override
  StatelessWidget get widget => super.widget;

  @override
  Widget build() => widget.build(this);

  @override
  void update(StatelessWidget newWidget) {
    super.update(newWidget);
    assert(widget == newWidget);
    _dirty = true;
    rebuild();
  }
}

结论

BuildContext对象实际上就是Element对象,build函数中所使用的context,正是当前widget所创建的Element对象。