Flutter 从浅入深理解 StatefulWidget 和 StatelessWidget

相关文章
Flutter 环境搭建以及填坑指南(Win10 系统且已有 Android 开发环境 )
Flutter 入门实现 ListView 列表页面以及收藏页面
Flutter Widget 静态布局实战
Flutter 容器类 Widget

简介

Flutter 中,一切皆 widget
那么什么是 widget 呢?

Widget 是 Flutter 功能的抽象描述,是视图的配置信息,同样也是数据的映射,是 Flutter 开发框架中最基本的概念。《引自极客时间-Flutter核心技术与实战》

Android开发的角度来看,widget类似于 Android 中的 View

AndroidView是最小的UI单位,widget 则是 Flutter 中最小的 UI 单位。

Widget
图片引自:What is Flutter?

从上图可看出 Widget 主要有两种类型:StatelessWidgetStatefulWidget
那么这两个 widget 有什么区别呢?

二者的区别:有无状态管理

StatelessWidget 中不需要管理Widget内部的状态。而 StatefulWidget中是需要管理Widget内部的状态,通过是通过setState来管理内部状态。

什么是状态管理呢?
我的理解是UI需要跟随用户的输入而进行改变

Demo 示例解析

我们可以查看官方的计数器DemoMyApp只需要承载MyHomePage,除此之外用户和UI没有直接的交互,因此这里使用StatelessWidget非常合适的。
在这里插入图片描述
再来看计数器Demo中点击按钮,计数器+1的代码
在这里插入图片描述
MyHomePage中需要根据用户和UI直接的交互,改变UI的值,因此这里使用StatefulWidget非常合适的。

为什么上面的描述我会用非常合适来形容呢?
因为StatefulWidget也能实现StateflessWidget的功能。
既然StateflessWidget是可被替代的,那么他的作用是什么呢?

通过上面的分析,我们知道二者的区别也就是StatefulWidget能通过setState()来改变widget的状态
那么我们从源码去找找,看看能找出StateflessWidget存在的意义吗?

源码分析StateflessWidget存在的意义

查看StatelessWidget,StatefulWidget源码如下:
在这里插入图片描述
源码中重写的内容,确实和我们在创建StatelessWidget,StatefulWidget是一样的。

那么接着往下查看,
找到了StatefulWidgetState抽象类中setState方法,发现了markNeedsBuild方法
这个方法的作用是:将element标记为脏元素,并将其添加到全局的widget中,调用了scheduleBuildFor方法在下一帧中重建。。
在这里插入图片描述
上面的源码出现了新的内容element,这又是什么东东呢?
仔细回看上面StatelessWidget,StatefulWidget的源码,发现二者都会有一个方法,如下:

/// Creates a [StatefulElement] to manage this widget's location in the tree.
///
/// It is uncommon for subclasses to override this method.

/// StatefulWidget
@override
StatefulElement createElement() => StatefulElement(this);

/// StatelessWidget
@override
StatelessElement createElement() => StatelessElement(this);

通过注释也可以了解到,这里的Element是用于管理在这个Widget范围下的所有widget,(Flutter 中万物皆widget,所以这个描述没毛病)。

点击深入源码发现StatefulElement 、StatelessElement都继承了ComponentElement
在这里插入图片描述
通过上面的注释我们可以了解到
为了和RenderObjectElement区分开,ComponentElement并不是直接创建RenderObject,而是通过其他 Element间接创建的。

这里又出现新的内容:RenderObject,这又是个什么东东?
RenderObject在源码中的第一个注释是:An object in the render tree.也就是渲染视图树上的一个对象。
在众多的注释中还说明了RenderObject是负责layout and paint protocols,也就是布局和绘制。

写到这里,我们不妨回想一下WidgetElement以及RenderObject三者的关系。

Widget是负责接收显示各个组件的绘制结果,而具体的绘制是通过创建RenderObject去绘制,RenderObject是通过RenderObjectElement创建,而RenderObjectElement又继承了Element

通过这么一顿分析,我们终于知道了Widget的生成过程。

回到setState的分析,我们发现StatefulElement在调用setState方法之后,该widget下的所有widget都会进行重建。

重建是需要耗时,所以StatefulElement 、StatelessElement的使用场景就比较明确了。

总结:

  1. 使用StatelessElement可提高UI的响应效率,优先使用StatelessElement,在需要改变状态的情况下使用StatefulElement
  2. Widget是负责接收显示各个组件的绘制结果,而具体的绘制是通过创建RenderObject去绘制,RenderObject是通过RenderObjectElement创建,而RenderObjectElement又继承了Element
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_龙衣

赏杯快乐水喝喝

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值