美文网首页
Flutter-State生命周期

Flutter-State生命周期

作者: JerrySi | 来源:发表于2019-08-01 09:39 被阅读0次
    1. State 的生命周期和 StatefulWidget 不同,当 StatefulWidget 状态改变后就会被重建,但是 State 不会改变,但是当 StatefulWidget 在 View 树中移除再插入又会生成新的 State。参考下文 State.context.
    2. initState -> build -> 状态改变 -> didUpdateWidget -> build --->移除.

    在学习 flutter 的时候,总会用到 StatefulWidget,它是一个有状态的 widget,会根据不同状态有不同显示,它的生命周期与 State 有关,它的基本写法如下

    // flutter官方教程里面的一个类,点击一个关注的星星,然后就表明已经关注。再点击表示不再关注,默认状态是已关注,关注数是41
    class FavoriteWidget extends StatefulWidget {
      @override
      _FavoriteWidgetState createState() => new _FavoriteWidgetState();
    }
    class _FavoriteWidgetState extends State<FavoriteWidget> {
      bool _isFavorited = true;
      int _favoriteCount = 41;
    
      void _toggleFavorite() {
        setState(() {
          // If the lake is currently favorited, unfavorite it. Otherwise, favorite it.
            _favoriteCount = _isFavorited?_favoriteCount -1:_favoriteCount +1 ;
            _isFavorited = !_isFavorited;
        });
      }
      @override
      Widget build(BuildContext context) {
        return new Widget(
            // build by states
        );
      }
    }
    

    将 FavoriteWidget 插入到 Views 树中的时候,每当调用 States.setState() 时,都会重新build一次FavoriteWidget ,然后将新的 Views代替原先的,并显示给用户。

    您可能想知道为什么 StatefulWidget 和 State 是单独的对象。在 Flutter 中,这两种类型的对象具有不同的生命周期: Widget 是临时对象,用于构建当前状态下的应用程序,而 State 对象在多次调用build()之间保持不变,允许它们记住信息(状态)。

    State的生命周期

    image

    总体介绍一下生命周期,大致可以看成三个阶段:

    • 初始化(插入渲染树)
    • 状态改变(在渲染树中存在)
    • 销毁(从渲染树种移除)

    先举 FavoriteWidget 为例,当这个 Widget 首次插入到树中时,框架会调用其 createState 函数以创建一个新的_FavoriteWidgetState实例来与该树中的相应位置关联(请注意,我们通常命名State子类时带一个下划线,这表示其是私有的)。 当这个widget的父级重建时,父级将创建一个新的FavoriteWidget实例,但是Flutter框架将重用已经在树中的_FavoriteWidgetState实例,而不是再次调用createState创建一个新的。

    从 StatefulWidget调用createState之后,框架将新的状态对象插入树中,然后调用 State 的initState,接着如上图所示走了一遍自身的生命周期。需要注意的是,StatefulWidget 和 State 是不同的生命周期。

    生命周期详解

    initState

    当插入渲染树的时候调用,这个函数在生命周期中只调用一次。这里可以做一些初始化工作,比如初始化State的变量。

    didChangeDependencies

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

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

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

    didUpdateWidget

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

    实际上这里flutter框架会创建一个新的Widget,绑定本State,并在这个函数中传递老的Widget。

    这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整。

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


    image
    image

    deactivate

    在dispose之前,会调用这个函数。

    dispose

    一旦到这个阶段,组件就要被销毁了,这个函数一般会移除监听,清理环境。‘

    总结

    阶段 调用次数
    构造函数 1
    initState 1
    didChangeDependencies >=1
    didUpdateWidget >=1
    deactivate >=1
    dispose 1

    各个方法的解释:

    • initState:插入渲染树时调用,只调用一次,widget创建执行的第一个方法,可以再里面初始化一些数据,以及绑定控制器
    • didChangeDependencies:当State对象的依赖发生变化时会被调用;例如:在之前build() 中包含了一个InheritedWidget,然后在之后的build() 中InheritedWidget发生了变化,那么此时InheritedWidget的子widget的didChangeDependencies()回调都会被调用。InheritedWidget这个widget可以由父控件向子控件共享数据,案例可以参考 scoped_model开源库。
    • build :它主要是用于构建Widget子树的,调用次数:多次,初始化之后开始绘制界面,当setState触发的时候会再次被调用
    • didUpdateWidget:组件状态改变时候调用,可能会调用多次
    • deactivate:当 State 被暂时从视图树中移除时,会调用这个函数。
      页面切换时,也会调用它,因为此时 State 在视图树中的位置发生了变化,需要先暂时移除后添加。
    • dispose():当State对象从树中被永久移除时调用;通常在此回调中释放资源。
    • reassemble:此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。

    相关文章

      网友评论

          本文标题:Flutter-State生命周期

          本文链接:https://www.haomeiwen.com/subject/wcttdctx.html