Flutter中Widget的生命周期和渲染原理

widget

FlutterWidget的生命周期

  • StatelessWidget是通过构造函数(Constructor)接收父Widget直接传入值,然后调用build方法来构建,整个过程非常简单
  • StatefulWidget需要通过State来管理其数据,并且还要监控状态的改变决定是否重新build整个Widget
  • 这里主要讨论StatefulWidget的生命周期,就是它从创建到显示再到更新最后到销毁的整个过程
  • StatefulWidget本身由两个类组成的:StatefulWidgetState
  • StatefulWidget中的相关方法主要就是
    • 执行StatefulWidget的构造函数(Constructor)来创建出StatefulWidget
    • 执行StatefulWidgetcreateState方法,来创建一个维护StatefulWidgetState对象
    • 所以我们探讨StatefulWidget的生命周期, 最终是探讨State的生命周期
  • 那么为什么Flutter在设计的时候, StatefulWidgetbuild方法要放在State中而不是自身呢
    • 首先build出来的Widget是需要依赖State中的变量(数据/自定义的状态)的
    • Flutter在运行过程中, Widget是不断的创建和销毁的, 当我们自己的状态改变时, 我们只希望刷新当前Widget, 并不希望创建新的State

图片来源网络

上面图片大概列出了StatefulWidget的简单的函数调用过程

constructor

调用createState创建State对象时, 执行State类的构造方法(Constructor)来创建State对象

initState

  • initStateStatefulWidget创建完后调用的第一个方法,而且只执行一次
  • 类似于iOSviewDidLoad,所以在这里View并没有完成渲染
  • 我们可以在这个方法中执行一些数据初始化的操作,或者发送网络请求
  @override
  void initState() {
    // 这里必须调用super的方法
    super.initState();
    print('4. 调用_HomeScreenState----initState');
  }
  • 这个方法是重写父类的方法,必须调用super,因为父类中会进行一些其他操作
  • 另一点在源码中, 会看到这个方法中有一个mustCallSuper的注解, 这里就限制了必须调用父类的方法
  @protected
  @mustCallSuper
  void initState() {
    assert(_debugLifecycleState == _StateLifecycle.created);
  }

didChangeDependencies

  • didChangeDependencies在整个过程中可能会被调用多次, 但是也只有下面两种情况下会被调用
  1. StatefulWidget第一次创建的时候didChangeDependencies会被调用一次, 会在initState方法之后会被立即调用
  2. 从其他对象中依赖一些数据发生改变时, 比如所依赖的InheritedWidget状态发生改变时, 也会被调用

build

  • build同样也会被调用多次
  • 在上述didChangeDependencies方法被调用之后, 会重新调用build方法, 来看一下我们当前需要重新渲染哪些Widget
  • 当每次所依赖的状态发生改变的时候build就会被调用, 所以一般不要将比较好使的操作放在build方法中执行

didUpdateWidget

执行didUpdateWidget方法是在当父Widget触发重建时,系统会调用didUpdateWidget方法

dispose

  • 当前的Widget不再使用时,会调用dispose进行销毁
  • 这时候就可以在dispose里做一些取消监听、动画的操作
  • 到这里, 也就意味着整个生命周期的过程也就结束了

setState

  • setState方法可以修改在State中定义的变量
  • 当我们手动调用setState方法,会根据最新的状态(数据)来重新调用build方法,构建对应的Widgets
  • setState内部其实是通过调用_element.markNeedsBuild();实现更新Widget

整个过程的代码如下:

class HomeScreen extends StatefulWidget {
  HomeScreen() {
    print('1. 调用HomeScreen---constructor');
  }
  @override
  _HomeScreenState createState() {
    print('2. 调用的HomeScreen---createState');
    return _HomeScreenState();
  }
}

class _HomeScreenState extends State<HomeScreen> {

  int _counter = 0;

  _HomeScreenState() {
    print('3. 调用_HomeScreenState----constructor');
  }

  @override
  void initState() {
    // 这里必须调用super的方法
    super.initState();
    print('4. 调用_HomeScreenState----initState');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('调用_HomeScreenState----didChangeDependencies');
  }
  
  @override
  Widget build(BuildContext context) {
    print('5. 调用_HomeScreenState----build');
    return Scaffold(
      appBar: AppBar(title: Text('生命周期', style: TextStyle(fontSize: 20))),
      body: Center(
        child: Column(
          children: <Widget>[
            Text('当前计数: $_counter', style: TextStyle(fontSize: 20),),
            RaisedButton(
              child: Text('点击增加计数', style: TextStyle(fontSize: 20),),
              onPressed: () {
                setState(() {
                  _counter++;
                });
              }
            )
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();

    print('6. 调用_HomeScreenState---dispose');
  }
}

打印结果如下:

flutter: 1. 调用HomeScreen---constructor
flutter: 2. 调用的HomeScreen---createState
flutter: 3. 调用_HomeScreenState----constructor
flutter: 4. 调用_HomeScreenState----initState
flutter: 调用_HomeScreenState----didChangeDependencies
flutter: 5. 调用_HomeScreenState----build

// 每次调用setState, 都会执行build
flutter: 5. 调用_HomeScreenState----build
flutter: 5. 调用_HomeScreenState----build

Flutter渲染原理

Flutter中渲染过程是通过Widget, ElementRenderObject实现的, 下面是FLutter中的三种树结构

Flutter

Widget

这是Flutter官网对Widget的说明

Flutter widgets are built using a modern framework that takes inspiration from React. The central idea is that you build your UI out of widgets. Widgets describe what their view should look like given their current configuration and state. When a widget’s state changes, the widget rebuilds its description, which the framework diffs against the previous description in order to determine the minimal changes needed in the underlying render tree to transition from one state to the next.

  • FlutterWidgets的灵感来自React,中心思想是使用这些Widgets来搭建自己的UI界面
  • 通过当前Widgets的配置和状态描述这个页面应该展示成什么样子
  • 当一个Widget发生改变时,Widget就会重新build它的描述,框架会和之前的描述进行对比,来决定使用最小的改变在渲染树中,从一个状态到另一个状态
  • 从这段说明中大概意思也就是
    • Widgets只是页面描述层面的, 并不涉及渲染层面的东西, 而且如果所依赖的配置和状态发生变化的时候, 该Widgets会重新build
    • 而对于渲染对象来说, 只会使用最小的开销重新渲染发生改变的部分而不是全部重新渲染
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值