Flutter 完整的生命周期(State状态管理)

一.Widget 树

  • 界面布局之后,会出现布局层级
  • 不论简单还是复杂布局都会有布局的嵌套层级
  • Widget树的展现形式
    • MyApp -> MaterialApp -> MyHomePage -> Scaffold -> AppBar、boday、floatingActionButton

二.Context 组件上下文

  • 对应组件中某一个Widget的位置引用
  • 每个Context对应一个Widget
  • 可以获取用来Widget的Rect

三.Widget 的唯一身份标识: key

  • 每个Widget都有唯一标识就是key,
  • 如果key 作为参数传入Widget里面,则会根据指定的名字生成key
  • 在有些场景下,你需要保存key,并且通过key访问该Widget
    可以通过GlobalKeyLocalKeyUniqueKeyObjectKey进行保存
  • 使用场景:复制操作,刷新组件等等

三、State完整的生命周期

1. 初始化

  • 构造函数(constructor)
  • initState : 只会调用一次
  • didChangeDependencies : Called when a dependency of this [State] object changes.(会执行多次)
  • Widget build

2. 状态变化

  • 热重载:reassemble 为了开发调试而提供,在Release模式下永远不会被调用
  • 组件状态(类中属性值)发生改变执行didUpdateWidget
  • widget build

3. 组件移除

  • 页面销毁的时候会依次执行:
    • deactivate : State对象从树中被移除时
    • dispose: state对象从树中被永久移除时调用;通常在此回调中释放资源

4. 切至后台

didChangeAppLifecycleState App生命周期发生变化
AppLifecycleState.inactive -> AppLifecycleState.paused

 

@override
  void didChangeAppLifecycleState(AppLifecycleState state){
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
      // app退到后台后, 刷新状态
    }
  }

5.切回前台

AppLifecycleState.inactive -> AppLifecycleState.resumed -> build

 

@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // app显示后, 刷新状态
    if (state == AppLifecycleState.resumed) {
      // 刷新代码
    }
  }

StatelessWidget - 生命周期

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

  • 无状态的Widget
  • 无法提供setState修改组件的状态
  • 内部属性应声明为final,防止意外发生改变

因此生命周期很简单

  • 初始化
  • 提供build渲染

、StatefulWidget - 生命周期

依次为

  • 构造函数
  • initState
  • didChangeDependencies
  • build
  • addPostFrameCallback
  • (组件状态改变)didUpdateWidget
  • deactivate
  • dispose

有状态生命周期

补充-状态管理

  • StatelessWidget(无状态)

一旦创建就不会发生变化,定义属性值可以变化,但不会重新渲染UI,

  • StatefulWidget(有状态)
  • state发生变化时会重新渲染UI,类似于Hot Reload
  • 更新/刷新操作:setState(() {});
  • createState 此方法返回状态管理类,进行关联

需要两个类去管理

  • 描述UI
  • 记录状态的State (w,h)不销毁,界面消失才会被干掉 : State属性改变时会根据宽高重新渲染UI

1.WidgetsBinding.instance.addPostFrameCallback

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

 

void initState() {
  super.initState();
  SchedulerBinding.instance.addPostFrameCallback((_) => {});
}

这个方法在一帧的最后调用,并且只调用一次,使用这个方法就可以在判断渲染完成,并获取到元素的大小。

 

@override
  void didChangeDependencies() {
    WidgetsBinding.instance.addPostFrameCallback(_onAfterRendering);
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(T oldWidget) {
    WidgetsBinding.instance.addPostFrameCallback(_onAfterRendering);
    super.didUpdateWidget(oldWidget);
  }


  void _onAfterRendering(Duration timeStamp){
      //这里编写获取元素大小和位置的方法
  }
  • 获取元素大小和位置:

 

//获取元素大小
RenderObject renderObject = context.findRenderObject();
Size size = renderObject.paintBounds.size;
//获取元素位置:
Vector3 vector3 = renderObject.getTransformTo(null)?.getTranslation();
//位置(vector3.x,vector3.y)



作者:StevenHu_Sir
链接:https://www.jianshu.com/p/6c214a054f90
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值