StatelessWidget和StatefulWidget

StatelessWidget

StatelessWidget:无状态组件,可以理解为将外部传入的数据转化为界面展示的内容,只会渲染一次 如果我们的Widget是StatelessWidget,那么当他的内容被创建出来之后,就不能再改变了。相反StatefulWidget就可以。 无状态Widget,就是说一旦这个Widget创建完成,状态就不允许再变动。有状态Widget,就是说当前Widget创建完成之后,还可以对当前Widget做更改,可以通过setState函数来刷新当前Widget来达到有状态。

StatefulWidget

StatefulWidget:有状态组件,是定义交互逻辑和业务数据,可以理解为具有动态可交互的内容界面,会根据数据的变化进行多次渲染。

1
2
StatelessWidget: Constructor -> build()  
StatefulWidget: Constructor -> createState() -> initState() ->build(),当有需求状态变化时setState() -> build()

StatefulWidget中的State

一个StatefulWidget类会对应一个State类,State表示与其对应的StatefulWidget要维护的状态,State中的保存的状态信息可以: 在widget 构建时可以被同步读取。 在widget生命周期中可以被改变,当State被改变时,可以手动调用其setState()方法通知Flutter framework状态发生改变, Flutter framework在收到消息后,会重新调用其build方法重新构建widget树,从而达到更新UI的目的。

StatefulWidget 的生命周期:

sss

Flutter 中的生命周期,包含以下几个阶段:

  • createState :该函数为 StatefulWidget 中创建 State 的方法,当 StatefulWidget 被调用时会立即执行 createState 。
  • initState :该函数为 State 初始化调用,因此可以在此期间执行 State 各变量的初始赋值,同时也可以在此期间与服务端交互,获取服务端数据后调用 setState 来设置 State。
  • didChangeDependencies :当State对象的依赖发生变化时会被调用;例如:在之前build() 中包含了一个InheritedWidget,然后在之后的build() 中InheritedWidget发生了变化,那么此时InheritedWidget的子widget的didChangeDependencies()回调都会被调用。典型的场景是当系统语言Locale或应用主题改变时,Flutter framework会通知widget调用此回调。
  • build :主要是返回需要渲染的 Widget ,由于 build 会被调用多次,因此在该函数中只能做返回 Widget 相关逻辑,避免因为执行多次导致状态异常。在 build 之后还有个回调 addPostFrameCallback,在当前帧绘制完成后会回调,注册之后不能被解注册并且只会回调一次; addPostFrameCallback是 SchedulerBinding 的方法;由于 mixin WidgetsBinding on SchedulerBinding,所以添加这个回调有两种方式:
1
2
3
SchedulerBinding.instance.addPostFrameCallback((_) => {});
或者
WidgetsBinding.instance.addPostFrameCallback((_) => {});
  • reassemble :在 debug 模式下,每次热重载都会调用该函数,因此在 debug 阶段可以在此期间增加一些 debug 代码,来检查代码问题。
  • didUpdateWidget :在widget重新构建时,Flutter framework会调用Widget.canUpdate来检测Widget树中同一位置的新旧节点,然后决定是否需要更新,如果Widget.canUpdate返回true则会调用此回调。正如之前所述,Widget.canUpdate会在新旧widget的key和runtimeType同时相等时会返回true,也就是说在在新旧widget的key和runtimeType同时相等时didUpdateWidget()就会被调用。父组件发生 build 的情况下,子组件该方法才会被调用,其次该方法调用之后一定会再调用本组件中的 build 方法。
  • deactivate :在组件被移除节点后会被调用,如果该组件被移除节点,然后未被插入到其他节点时,则会继续调用 dispose 永久移除。
  • dispose :永久移除组件,并释放组件资源。

Flutter 生命周期的整个过程可以分为四个阶段:

  • 初始化阶段:createState 和 initState
  • 组件创建阶段:didChangeDependencies 和 build
  • 触发组件 build:didChangeDependencies、setState 或者didUpdateWidget 都会引发的组件重新 build
  • 组件销毁阶段:deactivate 和 dispose