Flutter视图Widget生命周期

Flutter视图Widget生命周期

做为一个Android开发者,必定会对Activity的生命周期有这很深入的印象,而当你在使用Flutter时,其中Widget就是View,其生命周期就是从View建立到销毁的过程。 Widget分为StatelessWidgetStatefulWidget 两种,这两种Widget的生命周期分别以下。bash

StatelessWidget的生命周期

无状态Widget的生命周期很简单,它只有一个生命周期:build网络

build

build函数用来构建视图,每次页面刷新是被调用,典型的用法以下:app

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
      ),
    );
  }
}
复制代码

StatefulWidget的生命周期

StatefulWidget生命周期整理以下图:less

大体可分为三个阶段:

  • 初始化:插入渲染树
  • 运行中:在渲染树中存在
  • 销毁:从渲染树中移除
初始化阶段
createState

createState必须且仅执行一次,它用来建立state,当建立StatefulWidget时,该放方法被执行ide

initState

在建立StatefulWidget后,initState是第一个被调用的方法,同createState同样只被调用一次,此时widget的被添加至渲染树,mount的值会变为true,但并无渲染。能够在该方法内作一些初始化操做。在在override时要低啊用super.initState()函数

@override
void initState() {
  super.initState();
  ...
}
复制代码
didChangeDependencies

当widget第一次被建立时,didChangeDependencies紧跟着initState函数以后调用,在widget刷新时,该方法不会被调用。它会在“依赖”发生变化时被Flutter Framework调用,这个依赖是指widget是否使用父widget中InheritedWidget的数据。也便是只有在widget依赖的InheritedWidget发生变化以后,didChangeDependencies才会调用。 这种机制可使子组件在所依赖的InheritedWidget变化时来更新自身!好比当主题、locale(语言)等发生变化时,依赖其的子widget的didChangeDependencies方法将会被调用。ui

//经过继承InheritedWidget,将当前计数器点击次数保存在ShareDataWidget的data属性中:
class ShareDataWidget extends InheritedWidget {
  ShareDataWidget({
    @required this.data,
    Widget child
  }) :super(child: child);

  final int data; //须要在子树中共享的数据,保存点击次数

  //定义一个便捷方法,方便子树中的widget获取共享数据  
  static ShareDataWidget of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(ShareDataWidget);
  }

  //该回调决定当data发生变化时,是否通知子树中依赖data的Widget  
  @override
  bool updateShouldNotify(ShareDataWidget old) {
    //若是返回true,则子树中依赖(build函数中有调用)本widget
    //的子widget的`state.didChangeDependencies`会被调用
    return old.data != data;
  }
}

class _TestWidget extends StatefulWidget {
  @override
  __TestWidgetState createState() => new __TestWidgetState();
}
//而后咱们实现一个子组件_TestWidget,在其build方法中引用ShareDataWidget中的数据。
class __TestWidgetState extends State<_TestWidget> {
  @override
  Widget build(BuildContext context) {
    //使用InheritedWidget中的共享数据
    return Text(ShareDataWidget
        .of(context)
        .data
        .toString());
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    //父或祖先widget中的InheritedWidget改变(updateShouldNotify返回true)时会被调用。
    //若是build中没有依赖InheritedWidget,则此回调不会被调用。
    print("Dependencies change");
  }
}

复制代码

注意:若是_TestWidget的build方法中没有使用ShareDataWidget的数据,那么它的didChangeDependencies()将不会被调用,由于它并无依赖ShareDataWidget。在依赖改变以后build方法也会被调用,因此在大多数场景下都无需使用didChangeDependencies。然而若是你须要在依赖改变后执行一些昂贵的操做,好比网络请求,这时最好的方式就是在此方法中执行,这样能够避免每次build()都执行这些昂贵操做。this

build

build函数会在widget第一次建立时紧跟着didChangeDependencies方法以后和UI从新渲染是时调用。build只作widget的建立操做,若是在build里作其余操做,会影响UI的渲染效果spa

运行中
didUpdateWidget

当组件的状态改变的时候就会调用didUpdateWidget,好比调用了setState.code

销毁
deactivate

当要将State对象从渲染树中移除的时候,就会调用 deactivate 生命周期,这标志着 StatefulWidget将要销毁。页面切换时,也会调用它,由于此时State在视图树中的位置发生了变化可是State不会被销毁,而是从新插入到渲染树中。 重写的时候必需要调用 super.deactivate()

dispose

从渲染树中移除view的时候调用,State会永久的从渲染树中移除,和initState正好相反mount值变味false。这时候就能够在dispose里作一些取消监听操做。

总结:
函数 调用次数 调用时间
createState 1 第一次建立
initState 1 第一次建立
didChangeDependencies n 第一次建立和依赖变化时
build n 第一次建立和UI从新渲染时
didUpdateWidget n 第一次建立和UI从新渲染时
deactivate n state对象将要移除时
dispose 1 state对象移除
相关文章
相关标签/搜索