美文网首页Flutter烂笔头
Flutter中Widget的生命周期

Flutter中Widget的生命周期

作者: RidingWind2023 | 来源:发表于2019-06-05 20:44 被阅读120次

    前言

    和其他的视图框架比如android的Activity一样,flutter中的视图Widget也存在生命周期,生命周期的回调函数提现在了State上面。理解flutter的生命周期,对我们写出一个合理的控件至关重要。组件State的生命周期整理如下图所示:


    Widget 生命周期

    大致可以看成三个阶段

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

    构造函数

    这个函数不属于生命周期,因为这个时候State的widget属性为空,如果要在构造函数中访问widget的属性是行不通的。但是构造函数必然是要第一个调用的。

    initState

    /// Called when this object is inserted into the tree.
    当插入渲染树的时候调用,这个函数在生命周期中只调用一次。这里可以做一些初始化工作,比如初始化State的变量。

    didChangeDependencies

    /// Called when a dependency of this [State] object changes.

    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中,可以跨组件拿到数据。

    didUpdateWidget

    /// Called whenever the widget configuration changes.

    didUpdateWidget
    当组件的状态改变的时候就会调用didUpdateWidget,比如调用了setState.
    实际上这里flutter框架会创建一个新的Widget,绑定本State,并在这个函数中传递老的Widget。
    这个函数一般用于比较新、老Widget,看看哪些属性改变了,并对State做一些调整。
    需要注意的是,涉及到controller的变更,需要在这个函数中移除老的controller的监听,并创建新controller的监听。
    TabBar_didUpdateWidget
    _updateTabController

    deactivate

    /// Called when this object is removed from the tree.

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

    dispose

    /// Called when this object is removed from the tree permanently.

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


    dispose

    实际场景

    假设我们从A页面跳转到B页面, 那么A,B页面的生命周期会是怎样的呢?

    B页面进入初始化状态,依次执行4个函数:构造函数 > initState > didChangeDependencies > Widget build , 此时页面加载完成,进入运行态。
    此时A页面依次执行deactivate > build函数。注意 此时A页面并未卸载。

    然后我们假设B页面只有一个按钮,点击B页面中的按钮,改变按钮的文字,会执行widget的build方法 ,(理论上也应该执行didUpdateWidget,但我这里没有)。

    这时,我们点击返回键从B页面返回到A页面。
    A页面重新显示,B页面开始卸载。
    那么A先执行deactivate > build , 然后B页面依次执行:deactivate > dispose 。
    此时A页面进入运行态,B页面移除。

    总结一下

    阶段 调用次数 是否支持setState
    构造函数 1
    initState 1 无效(使用setState和不使用一样)
    didChangeDependencies >=1 无效
    didUpdateWidget >=1
    deactivate >=1
    dispose 1

    如果你觉得这篇文章对你有益,还请帮忙转发和点赞,万分感谢。

    Flutter烂笔头
    您的关注将是我坚持的动力源泉,再次感谢。

    相关文章

      网友评论

        本文标题:Flutter中Widget的生命周期

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