一,概述

Flutter 的生命周期分为两个部分:

  • Widget 的生命周期
  • App 的生命周期

二,Widget 的生命周期

Flutter 里的 Widget 分为 StatelessWidget 和 StatefulWidget 两种,这两种 Widget 的生命周期是不一样的,我们接下来具体来看。

  • StatelessWidget 的生命周期

    StatelessWidget 的生命周期只有一个,就是:

    • build

      build 是用来创建 Widget 的,但因为 build 在每次界面刷新的时候都会调用,所以不要在 build 里写业务逻辑,可以把业务逻辑写到你的 StatelessWidget 的构造函数里。

      StatelessWidget 的 build 函数代码如下:

      class TestWidget extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
      // TODO: implement build
      print('StatelessWidget build');
      return Text('Test');
      }
      }
  • StatefulWidget 的生命周期

    • StatefulWidget 的生命周期比较复杂,依次为:

      • createState
      • initState
      • didChangeDependencies
      • build
      • addPostFrameCallback
      • didUpdateWidget
      • deactivate
      • dispose

    • 生命周期图
    • 接下来具体介绍一下各个生命周期。
      • createState

        createState 是 StatefulWidget 里创建 State 的方法,当要创建新的 StatefulWidget 的时候,会立即执行 createState,而且只执行一次,createState 必须要实现:

        class MyScreen extends StatefulWidget {
        @override
        _MyScreenState createState() => _MyScreenState();
        }
      • initState

        前面的 createState 是在创建 StatefulWidget 的时候会调用,initState 是 StatefulWidget 创建完后调用的第一个方法,而且只执行一次,类似于 Android 的 onCreate、iOS 的 viewDidLoad(),所以在这里 View 并没有渲染,但是这时 StatefulWidget 已经被加载到渲染树里了,这时 StatefulWidget 的 mount的值会变为 true,直到 dispose调用的时候才会变为 false。可以在 initState里做一些初始化的操作。

        在 override initState的时候必须要调用 super.initState():

        @override
        void initState() {
        super.initState();
        ...
        }
      • didChangeDependencies

        当 StatefulWidget 第一次创建的时候,didChangeDependencies方法会在 initState方法之后立即调用,之后当 StatefulWidget 刷新的时候,就不会调用了,除非你的 StatefulWidget 依赖的 InheritedWidget 发生变化之后,didChangeDependencies才会调用,所以 didChangeDependencies有可能会被调用多次。

        这个函数会紧跟在initState之后调用,并且可以调用BuildContext.inheritFromWidgetOfExactType,那么BuildContext.inheritFromWidgetOfExactType的使用场景是什么呢?最经典的应用场景是

        new DefaultTabController(length: 3, child: new TabBar(
        tabs: [ "主页","订单","我的" ]
        .map( (data)=>new Text(data) ).toList(),

        TabBar本来需要定义一个TabController,但是在外面套一层DefaultTabController就不需要定义TabContrller了,看下源码:

        @override
        void didChangeDependencies() {
        super.didChangeDependencies();
        _updateTabController();
        _initIndicatorPainter();
        } void _updateTabController() {
        final TabController newController = widget.controller ?? DefaultTabController.of(context);
        ...
        }

        注意到这里DefaultTabController.of(context)

        static TabController of(BuildContext context) {
        final _TabControllerScope scope = context.inheritFromWidgetOfExactType(_TabControllerScope);
        return scope?.controller;
        }

        实际上就是调用BuildContext.inheritFromWidgetOfExactType,也就说在didChangeDependencies中,可以跨组件拿到数据。

      • build

        在 StatefulWidget 第一次创建的时候,build方法会在 didChangeDependencies方法之后立即调用,另外一种会调用 build方法的场景是,每当 UI 需要重新渲染的时候(setState触发),build都会被调用,所以 build会被多次调用,然后 返回要渲染的 Widget。千万不要在 build里做除了创建 Widget 之外的操作,因为这个会影响 UI 的渲染效率。

      • addPostFrameCallback

        addPostFrameCallback是 StatefulWidge 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用,addPostFrameCallback的使用方法是在 initState里添加回调:

        import 'package:flutter/scheduler.dart';
        @override
        void initState() {
        super.initState();
        SchedulerBinding.instance.addPostFrameCallback((_) => {});
        }
      • didUpdateWidget

        祖先节点rebuild widget时调用 .当组件的状态改变的时候就会调用didUpdateWidget.(可能会调用多次)

        理论上setState的时候会调用,但我实际操作的时候发现只是做setState的操作的时候没有调用这个方法。而在我改变代码hot reload时候会调用 didUpdateWidget 并执行 build…

        实际上这里flutter框架会创建一个新的Widget,绑定本State,并在这个函数中传递老的Widget。这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整。

        需要注意的是,涉及到controller的变更,需要在这个函数中移除老的controller的监听,并创建新controller的监听。

      • deactivate(组件移除时)

        当要将 State 对象从渲染树中移除的时候,就会调用 deactivate生命周期,这标志着 StatefulWidget 将要销毁,但是有时候 State 不会被销毁,而是重新插入到渲染树种。

      • dispose(组件移除时)

        当 View 不需要再显示,从渲染树中移除的时候,State 就会永久的从渲染树中移除,就会调用 dispose生命周期,这时候就可以在 dispose里做一些取消监听、动画的操作,和 initState是相反的。

三,App 的生命周期

AppLifecycleState 就是 App 的生命周期,有:

  • resumed
  • inactive
  • paused
  • suspending

如果想要知道 Flutter App 的生命周期,例如 Flutter 是在前台还是在后台,就需要使用到 WidgetsBindingObserver了,使用方法如下:

  1. State 的类 mix WidgetsBindingObserver:

    class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
    ...
    }
  2. 在 State 的 initState里添加监听:

    @override
    void initState(){
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    }
  3. 在 State 的 dispose里移除监听:

     @override
    void dispose() {
    // TODO: implement dispose
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
    }
  4. 在 State 里 override didChangeAppLifecycleState

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
    // went to Background
    }
    if (state == AppLifecycleState.resumed) {
    // came back to Foreground
    }
    }

最新文章

  1. centos6搭建gitlab
  2. Android—ZXing二维码扫描遇到的问题
  3. Swfit 字符与字符串
  4. AC日记——逃出克隆岛 (bfs)
  5. TYVJ P1073 加分二叉树 Label:区间dp
  6. jsp struts标签迭代各种数据
  7. This application failed to start because it could not find or load the Qt platform plugin “windows”错误解决方法
  8. 适配iOS10以及Xcode8-b
  9. Kinetic使用注意点--lable
  10. cocos2d-x过程动作CCProgressTo示例学习笔记
  11. 用js把图片做的富有动态感,并对以后需要用着的属性进行封装
  12. [Ubuntu] 14.04 关闭桌面
  13. MYSQL如何计算两个日期间隔天数
  14. mapreduce join
  15. HDU 2052 Picture
  16. 继承数组的slice方法
  17. Java基础91 mysql的用户权限设置问题
  18. 【Java】第一讲:Java基础
  19. Linux基础命令---tune2fs
  20. oracle多表查询之内连接,外连接语句总结

热门文章

  1. DOS基础使用专题(强烈推荐)2
  2. PHP curl_error函数
  3. 4412 GPIO读 和 ioremap控制GPIO寄存器
  4. delphi 创建桌面快捷方式
  5. 23-25 October in 614
  6. Borůvka (Sollin) 算法求 MST 最小生成树
  7. mysql启动以及常用命令汇总
  8. python中模块介绍
  9. python练习题自己实现一个字符串的find函数
  10. jenkins配置到gitlab拉代码