0
点赞
收藏
分享

微信扫一扫

搜维尔科技:TechViz 虚拟现实在工业项目中沉浸式体验

圣杰 04-04 19:00 阅读 1

1.Widget概念

  • 字面意思就是 装饰物/小部件,在Flutter中几乎所有的对象都是一个 widget。
  • Widget 的功能是“描述一个UI元素的配置信息”(所谓的配置信息就是 Widget 接收的参数,比如对于 Text 来讲,文本的内容、对齐方式、文本样式都是它的配置信息)。
  • 与原生相比,原生开发中的“控件”通常只是指UI元素,Flutter 中的 widget 的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector 、用于APP主题数据传递的 Theme 等等。

2.Widget中的接口

Widget类本身是一个抽象类。其中最核心的就是定义了createElement()接口,在 Flutter 开发中,我们一般都不用直接继承Widget类来实现一个新组件,相反,我们通常会通过继承StatelessWidgetStatefulWidget来间接继承widget类来实现。

Widget源码如下:

 // 不可变的
abstract class Widget extends DiagnosticableTree {
   
  const Widget({
    this.key });

  final Key? key;

  
  
  Element createElement();

  
  String toStringShort() {
   
    final String type = objectRuntimeType(this, 'Widget');
    return key == null ? type : '$type-$key';
  }

  
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
   
    super.debugFillProperties(properties);
    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
  }

  
  
  bool operator ==(Object other) => super == other;

  
  
  int get hashCode => super.hashCode;

  static bool canUpdate(Widget oldWidget, Widget newWidget) {
   
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }
  ...
}

3.Flutter中的四棵树

  1. Widget 树
  2. Element 树
  3. Render 树(渲染树)
  4. Layer 树

既然 Widget 只是描述一个UI元素的配置信息,那么真正的布局、绘制是由谁来完成的呢?Flutter 框架的处理流程是这样的:

  • 根据 Widget 树生成一个 Element 树。(Element 树中的节点都继承自 Element 类)
  • 根据 Element 树生成 Render 树。(渲染树中的节点都继承自RenderObject 类)
  • 根据渲染树生成 Layer 树,然后上屏显示。(Layer 树中的节点都继承自 Layer 类)

真正的布局和渲染逻辑在 Render 树中,Element 是 Widget 和 RenderObject 的粘合剂,可以理解为一个中间代理。

我们通过一个例子来说明,假设有如下 Widget 树:

Container( // 一个容器 widget
  color: Colors.blue, // 设置容器背景色
  child: Row( // 可以将子widget沿水平方向排列
    children: [
      Image.network('https://www.example.com/1.png'), // 显示图片的 widget
      const Text('A'),
    ],
  ),
);

注意,如果 Container 设置了背景色,Container 内部会创建一个新的 ColoredBox 来填充背景,相关逻辑如下:

if (color != null)
  current = ColoredBox(color: color!, child: current);

而 Image 内部会通过 RawImage 来渲染图片、Text 内部会通过 RichText 来渲染文本,所以最终的 Widget树、Element 树、渲染树结构如下图所示:

image.png

这里需要注意:

  1. 三棵树中,Widget 和 Element 是一一对应的,但并不和 RenderObject 一一对应。比如 StatelessWidget 和 StatefulWidget 都没有对应的 RenderObject。
  2. 渲染树在上屏前会生成一棵 Layer 树,这个会在后面原理篇再介绍,目前只需要记住以上三棵树就行。

4.StatelessWidget

4.1 源码

abstract class StatelessWidget extends Widget {
   
  /// Initializes [key] for subclasses.
  const StatelessWidget({
    Key? key }) : super(key: key);

  /// 重写了 widget 类的 createElement()方法,返回了StatelessElement
  
  StatelessElement createElement() => StatelessElement(this);

  
  Widget build(BuildContext context);
}

StatelessWidget相对比较简单,它继承自widget类,重写了createElement()方法:


StatelessElement createElement() => StatelessElement(this);

StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。
StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其他 widget 来构建UI,在构建过程中会递归的构建其嵌套的 widget 。

我们看一个简单的例子:

class Echo exte
举报

相关推荐

0 条评论