阅读 215

Flutter(三十二)-Widget生命周期

Flutter中的WidgetAndroid中的ActivityiOS中的UIViewController一样,也是存在生命周期的,所谓的生命周期也就是回调函数,通过这些回调函数可以让我们知道当前Widget所处的状态;

生命周期的作用

Widget出在不同的时间状态时,会有不同的生命周期回调函数执行,在这些回调函数中我们可以做不同的事情:

  • 初始化数据

    • 变量和常量的创建

    • 网络请求的发送

  • 监听Widget的事件

  • 内存的管理

    • 数据或者监听者的销毁

    • 定时器TImer的销毁

Widget的生命周期

众所周知,在FlutterWidget分为:有状态无状态两种,并且有状态Widget明显要比无状态Widget要复杂的多,那么他们的生命周期会不会有什么不同呢?

StatelessWidget的生命周期

我们在界面上加载一个简单的StatelessWidget的页面,给页面传值title

image.png

image.png

很明显,我们在Flutter中创建一个Widget的时候,使用的都是构造方法,比如此处的LessLifeCycleDemo的构造方法LessLifeCycleDemo(title: "无状态Widget生命周期"),而buildWidget渲染时会调用的方法;我们分别在两个方法中添加打印信息:

image.png

这是StatelessWidget的生命周期,其相对简单;我们接下来主要介绍一下StatefulWidget的生命周期;

StatefulWidget的生命周期

我们编写如下代码,在我们已知的生命周期方法中添加打印信息:

image.png

最终打印顺序如下:

image.png

然后点击加号按钮:

iShot2021-11-27 14.33.54.gif

在调用setState方法是,只有build方法会被触发执行;

目前我们使用到的生命周期的函数还比较少,除了目前所用的,还有其他周期函数:

  • didChangeDependencies():当State对象的依赖发生变化是被调用;典型的场景就是系统语言改变或者主题发生变化时,Flutter框架会通知Widget调用此回调;

  • reassemble():此回调只在开发调试的过程中生效,在热重载hot reload时被调用,在Release模式下永远不会回调;

  • didUpdateWidget():在Widget重新构建时,Flutter框架会调用widget.canUpdate来检测Widget树上同一位置的新旧两个节点,然后判断是否需要进行更新,如果返回true,则调用此回调;

    • widget.canUpdate会在新旧widgetkeyruntimeType同时相等时返回true;这个我们在后边渲染原理时会讲到;

  • deactivate():当State对象从树中被移除时,会调用此回调;在某些场景下,Flutter框架会将State对象重新插入到树中,比如包含此State对象的子树从树一个位置移动到另一个位置时(可通过GlobalKey来实现)。

    • 如果移除后,没有重新插入到树中,则会直接调用dispose()方法进行销毁;

触发build方法的场景

我们都知道build方法在用于构建渲染Widget是会被调用,触发build方法有以下几个:

  • 调用initState()之后

  • 调用didUpdateWidget()之后

  • 调用setState()之后

  • 调用didChangeDependencies()之后

  • State对象从树的一个位置移除后(会调用deactivate()),又重新插入到树的其他位置之后

setState触发build的本质

我们都知道调用setState方法将会触发build方法的执行,那么为什么build方法会被执行呢?我们来看一下setState的源码:

image.png

我们可以看到setState方法的实现中,最重要的就是_element!.markNeedsBuild()方法,标记需要被渲染;那么_element是什么呢?我们从上文代码中可以看到:

image.png

_element本质上就是BuildContext,那么我们是否可以直接使用context调用markNeedsBuild方法来触发build呢?我们将代码修改如下:

image.png

运行结果:

iShot2021-11-27 15.11.04.gif

build方法被触发;

Android Studio中的一个bug

正常情况下,我们在编译器中打印的生命周期的信息只会执行一次,比如我们热重载的时候,方法执行如下:

image.png

但是,当我们重新执行项目的时候,却会出现下边的情况:

image.png

生命周期方法被调用了两次,这是Android Studio的一个bug,我们可以使用Xcode来验证一下,在Xcode中直接运行项目是不会出现这种情况的:

image.png


作者:枸杞菊花保温杯
链接:https://juejin.cn/post/7036161040693854222

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐