Fork me on GitHub

Widget生命周期的理解

什么是生命周期呢?

做过Android/iOS开发的都知道我们的页面都是由生命周期,我们在不同生命周期的回调方法里会做一些处理。对于flutter而言 一切皆是Widget,所以了解Widget的生命周期也是必不可少的!

  • 客户端开发:iOS开发中我们需要知道UIViewController从创建到销毁的整个过程,Android开发中我们需要知道Activity从创建到销毁的整个过程。以便在不同的生命周期方法中完成不同的操作;

  • 前端开发中:Vue、React开发中组件也都有自己的生命周期,在不同的生命周期中我们可以做不同的操作;

 

Flutter小部件的生命周期

一、StatelessWidget生命周期

 

  • StatelessWidget可以由父Widget直接传入值,调用build方法来构建,整个过程非常简单;下图是官网对StateLessWidget 生命周期的描述,不难看出StateLessWidget只有两个过程,初始化和build。

 

StatelessWidget的生命周期
class JGHomeContent extends StatelessWidget {
 final String message;

 JGHomeContent(this.message) {
   print("构造函数被调用");
 }

 @override
 Widget build(BuildContext context) {
   print("调用build方法");
   return Text(message);
 }
}

 

二、StatefulWidget生命周期

  • 而StatefulWidget需要通过State来管理其数据,并且还要监控状态的改变决定是否重新build整个Widget;
  • StatefulWidget是有状态的Widget,Widget创建出来之后是不可变,但是状态是可以变的,管理这个状态的就是State,我们可以通过调用期setState方法去刷新Widget。

 

 

在下图中,灰色部分的内容是Flutter内部操作的,我们并不需要手动去设置它们;

白色部分表示我们可以去监听到或者可以手动调用的方法;

我们知道StatefulWidget本身由两个类组成的:StatefulWidgetState,我们分开进行分析

 

 

 

 

首先,执行StatefulWidget中相关的方法:

  • 1、执行StatefulWidget的构造函数(Constructor)来创建出StatefulWidget;

  • 2、执行StatefulWidget的createState方法,来创建一个维护StatefulWidget的State对象;

其次,调用createState创建State对象时,执行State类的相关方法:

  • 1、执行State类的构造方法(Constructor)来创建State对象;

  • 2、执行initState,我们通常会在这个方法中执行一些数据初始化的操作,或者也可能会发送网络请求;

    • 注意:这个方法是重写父类的方法,必须调用super,因为父类中会进行一些其他操作;

    • 并且如果你阅读源码,你会发现这里有一个注解(annotation):@mustCallSuper

  • 3、执行didChangeDependencies方法,这个方法在两种情况下会调用 

    • 情况一:调用initState会调用;

    • 情况二:从其他对象中依赖一些数据发生改变时,比如前面我们提到的InheritedWidget(这个后面会讲到);

  • 4、Flutter执行build方法,来看一下我们当前的Widget需要渲染哪些Widget;

  • 5、当前的Widget不再使用时,会调用dispose进行销毁;

  • 6、手动调用setState方法,会根据最新的状态(数据)来重新调用build方法,构建对应的Widgets;

  • 7、执行didUpdateWidget方法是在当父Widget触发重建(rebuild)时,系统会调用didUpdateWidget方法;

下图是关于StateStatefulElementComponentElement的关系图,可以更好的理解StatefulWidget的生命周期。

 

 

总结下StatefulWidget生命周期:
  • initState 适合做初始化工作
  • build 避免在build内做些逻辑代码,因为在调用setState是build方法会重新触发,容易产生问题
  • dispose 释放资源。

 

 

// StatefulWidget的生命周期
class JGHomeContent extends StatefulWidget {
  JGHomeContent() {
    print("1.调用JGHomeContent的constructor方法");
  }

  @override
  _JGHomeContentState createState() {
    print("2.调用JGHomeContent的createState方法");
    return _JGHomeContentState();
  }
}

class _JGHomeContentState extends State<JGHomeContent> {
  int _counter = 0;
  _JGHomeContentState() {
    print("3.调用_JGHomeContentState的constructor方法");
  }

  @override
  void initState() {
    // 调用: 这里是必须调用super
    final TextStyle style = TextStyle();

    super.initState();
    print("4.调用_JGHomeContentState的initState方法");
  }

  @override
  void didUpdateWidget(JGHomeContent oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget");
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print("调用_JGHomeContentState的didChangeDependencies方法");
  }

  @override
  Widget build(BuildContext context) {
    print("5.调用_JGHomeContentState的build方法");
    return Column(
      children: <Widget>[
        RaisedButton(
          child: Icon(Icons.add),
          onPressed: () {
            setState(() {
              _counter++;
            });
          },
        ),
        Text("数字:$_counter")
      ],
    );
  }

  @override
  void dispose() {
    print("6.调用_JGHomeContentState的dispose方法");
    super.dispose();
  }
}

 

posted @ 2021-12-05 15:37  极度恐慌_JG  阅读(497)  评论(0编辑  收藏  举报