前言
使用过Flutter的同学,应该都听过一句话“everything is a widget——在Flutter中万物皆是Widget”。
这句话虽然不能说,Flutter开发所有代码模块都是一个Widget,但足以说明Widget在Flutter中的重要性,本篇文章就重点关于Flutter Widget的原理进行解读。
Widget简介
什么是Widget?我们先看一下官方的描述
“Describes the configuration for an [Element]”
在Flutter中,Widget的功能是“描述一个UI元素的配置数据”。
这句话很简单,如何理解呢?暂时可以简单的理解,FLutter最终绘制在设备上的显示元素,都是通过Widget配置出来的。
在web前端开发中,我们知道浏览器页面由HTML+CSS+JS配置而成,其中HTML负责配置UI结构,CSS负责配置UI样式,JS负责UI的交互。
而在Flutter中,无论是UI结构,还是UI样式,再到UI交互都是通过Widget完成。例如:
- Widget树结构配置UI结构
- 样式Widget,Padding、Color等
- 交互Widget,GestureDetector等
Widget分类
在Flutter中,官方提供的原生Widget多达300+,这么多Widget,在基础原理层面是如何分类的呢?
使用过Flutter的同学,最熟悉的应该是StatelessWidget和StatefulWidget两种Widget,除了这两种还要其他的吗?
我们来看一下Flutter Widget组件继承图。
从上图中,我们知道继承Widget基类四个子类分别是
- StatelessWidget
- StatefulWidget
- RenderObjectWidget
- ProxyWidget
其中前三类StatelessWidget、StatefulWidget、RenderObjectWidget负责UI渲染配置,而ProxyWidget继承的子类InheritedWidget负责Widget树向下传递数据。
如果按照功能来分类,则可分成两大类:
- UI渲染配置Widget:StatelessWidget、StatefulWidget、RenderObjectWidget
- UI树数据状态管理Widget:InheritedWidget
StatelessWidget、StatefulWidget、RenderObjectWidget又可依据UI配置类型Widget,分成两类:
- 组合Widget:StatelessWidget、StatefulWidget
- 自定义渲染Widget:RenderObjectWidget
接下来,本篇文章主要讲解UI配置类型Widget,UI树数据状态管理Widget——InheritedWidget,将在下一篇文章中讲解。
组合Widget自定义渲染Widget区别?
在日常业务开发中,开发者只需要使用组合Widget就能
满足99%的业务功能,所以对于初学Flutter的同学来说,学会StatelessWidget与StatefulWidget的使用就能满足业务开发需求。
组合Widget与自定义渲染Widget有什么区别呢?
站在前端的角度,我们开发一个HTML页面,只需要使用W3C定义的标准的div、span等标签和css样式position、color等即可搭建一个完整的页面。
至于div、color浏览器最终是如何渲染的,无需开发者定义实现,全权由浏览器引擎原生实现。开发者基于div+css开发的组件都属于组合组件,等同于组合Widget。
那什么是自定义渲染Widget呢?就好比,浏览器未支持css3之前,如果要实现边框圆角样式“border-radius”使用css是做不到的。假如浏览器提供前端开发者自定义css样式渲染的接口,由前端开发者实现边框圆角的css渲染,则属于自定义渲染组件,等同于与自定义渲染Widget。
组合Widget,StatelessWidget与StatefulWidget
我们先看看,源码抽象类的定义
StatelessWidget源码
abstract class StatelessWidget extends Widget {
const StatelessWidget({ Key? key }) : super(key: key);
@override
StatelessElement createElement() => StatelessElement(this);
@protected
Widget build(BuildContext context);
}
StatefulWidget