文章

01.Flutter Widget

01.Flutter Widget

Flutter Widget

Widget 概念

在 Flutter 中几乎所有的对象都是一个 widget;Flutter 中万物皆为 Widget。
Flutter 中的 widget 的概念更广泛,它不仅可以表示 UI 元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector 、用于 APP 主题数据传递的 Theme 等等

Widget 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@immutable
abstract class Widget extends DiagnosticableTree {
	const Widget({ this.key });
  
  final Key? key;
  
  @protected
  @factory
  Element createElement();
  
  @override
  String toStringShort() {
    final String type = objectRuntimeType(this, 'Widget');
    return key == null ? type : '$type-$key';
  }

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

  @override
  @nonVirtual
  bool operator ==(Object other) => super == other;

  @override
  @nonVirtual
  int get hashCode => super.hashCode;
  
  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }

  static int _debugConcreteSubtype(Widget widget) {
    return widget is StatefulWidget ? 1 :
           widget is StatelessWidget ? 2 :
           0;
  }
}

Flutter 中的四棵树

Widget

Element

RenderObject

Layer

StatelessWidget 和 StatefulWidget

StatelessWidget

什么是 StatelessWidget?

StatelessWidget 是一个不需要状态更改的 widget:它没有要管理的内部状态。
当你描述的用户界面部分不依赖于对象本身中的配置信息以及 widget 的 BuildContext 时,用 StatelessWidget。

哪些组件是无状态的?

  1. AboutDialog
  2. CircleAvatar
  3. Text
  4. Row
  5. Column
  6. Container

它们都是 StatelessWidget 子类。

无状态的 widget 的 build 方法通常只会在以下三种情况调用

  1. 将 widget 插入树中
  2. 当 widget 的父级更改其配置时
  3. 当它依赖的 InheritedWidget 发生变化时

BuildContext

BuildContext 表示当前 widget 在 widget 树中的上下文,每一个 widget 都会对应一个 context 对象(因为每一个 widget 都是 widget 树上的一个节点)
实际上,context 是当前 widget 在 widget 树中位置中执行 “ 相关操作 “ 的一个句柄 (handle),比如它提供了从当前 widget 开始向上遍历 widget 树以及按照 widget 类型查找父级 widget 的方法。

StatefulWidget

什么是 StatefulWidget?

StatefulWidget 是可变状态的 widget。使用 setState 方法管理 StatefulWidget 的状态改变。调用 setState 告诉 Flutter 框架,某个状态发生了变化,Flutter 会重新运行 build 方法,以便应用程序可以应用最新状态。
状态是在构建 widget 时可以同步读取的信息可能会在 widget 生命周期变化时发生变化。确保在状态改变时及时通知状态变化是 widget 实现者的责任。例如:通过键入表单或移动滑块来更改 widget 的状态,或者它可以随时间的变化或者数据推送更新 UI。

哪些组件是 StatefulWidget 子类?

  1. Checkbox
  2. Radio
  3. Slider
  4. InkWell
  5. Form
  6. TextField

StatefulWidget 和 StatelessWidget 抉择?

一个 Widget 是有状态还是无状态的,取决于它是否依赖状态的变化:

  • 如果用户交互或数据改变导致 widget 改变,那么它就是有状态的。
  • 如果一个 widget 是最终的或不可变的,那么它就是无状态的。

Flutter 有三种管理状态方式:

  1. 每个 widget 管理自己的状态
  2. 父 widget 管理 widget 的状态
  3. 混合搭配管理的方法

谁来管理 widget 的状态?

  1. 如果所讨论的状态是用户数据,例如复选框的已选中或未选中状态,滑动的位置,状态最好是由父 widget 来管理
  2. 如果 widget 的状态取决于动画,例如动画,那么最好是由 widget 自身来管理状态
  3. 如果不确定谁来管理状态,请让父 widget 管理子 widget 的状态
本文由作者按照 CC BY 4.0 进行授权