Widgets 翻译成中文就是小插件的意思Widgets 是 Flutter 中用户界面的基础;你在 flutter 界面中能够观察到的用户界面,都是 Widgets
当然这些大的 Widgets 又是由一个个的小的Widgets 组成的,而这些小的 Widgets 又是由更小的 Widgets 组成的;这样就构成了 Widgets 的层次依赖结构,这些层次结构的关联关系是通过 Widget 中的 child Widget 进行关联的
在这种层次结构中,子 Widgets 可以共享父 Widgets 的上下文环境
他们最大的不同是,Flutter 中的 Widgets 更多,每个 Widgets 专注的功能更小;即便是一个很小很小功能,在 Flutter 中都可以找到与之对应的 Widgets
这样做的好处就是,你可以使用不同的,非常基础的 Widgets 任意组合,从而构建出非常复杂的,个性化的大的 Widgets
当然,它的缺点也非常明显,就是代码里面的 Widgets 太多了,导致代码中的层级结构特别的多,可能会看的眼花缭乱
举个简单的例子,Container 是 flutter 提供的一个基本的容器 Widget,我们通常这样来使用它:
Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.headline4!.fontSize! * 1.1 + 200.0,
),
padding: const EdgeInsets.all(8.0),
color: Colors.blue[600],
alignment: Alignment.center,
child: Text('Hello World',
style: Theme.of(context)
.textTheme
.headline4!
.copyWith(color: Colors.white)),
transform: Matrix4.rotationZ(0.1),
)
我们向 Container 中传入了 constraints,padding,color,alignment,child,transform 等信息
大家第一时间想到的应该是 child,它本身就是一个 Widget,用来表示 Container 中包含的子对象,这个很好理解
但是,除了 child 这个 Widget 之外,其他的 constraints,padding,color,alignment,transform 等都是构成 Widget 的元素!
Widget build(BuildContext context) {
Widget? current = child;
if (child == null && (constraints == null || !constraints!.isTight)) {
current = LimitedBox(
maxWidth: 0.0,
maxHeight: 0.0,
child: ConstrainedBox(constraints: const BoxConstraints.expand()),
);
}
if (alignment != null)
current = Align(alignment: alignment!, child: current);
final EdgeInsetsGeometry? effectivePadding = \_paddingIncludingDecoration;
if (effectivePadding != null)
current = Padding(padding: effectivePadding, child: current);
if (color != null)
current = ColoredBox(color: color!, child: current);
if (clipBehavior != Clip.none) {
assert(decoration != null);
current = ClipPath(
clipper: \_DecorationClipper(
textDirection: Directionality.maybeOf(context),
decoration: decoration!,
),
clipBehavior: clipBehavior,
child: current,
);
}
if (decoration != null)
current = DecoratedBox(decoration: decoration!, child: current);
if (foregroundDecoration != null) {
current = DecoratedBox(
decoration: foregroundDecoration!,
position: DecorationPosition.foreground,
child: current,
);
}
if (constraints != null)
current = ConstrainedBox(constraints: constraints!, child: current);
if (margin != null)
current = Padding(padding: margin!, child: current);
if (transform != null)
current = Transform(transform: transform!, alignment: transformAlignment, child: current);
return current!;
从代码中可以看到,Container 先是创建了 LimitedBox,然后将其嵌入到 Align 中,再依次嵌入到 Padding,ColoredBox,ClipPath,DecoratedBox,ConstrainedBox,Padding 和 Transform 中;这些所有的对象都是 Widget
这里应该可以理解 Flutter 中 Widget 的设计思想了;在 Flutter 中一切皆可为 Widget
和其他的编译成原生语言特性的跨平台实现如 React native 相比,Flutter 对于每个 UI 都有自己的实现,而不是依赖于操作系统提供的接口
这样做的好处就是一切都是由 Flutter 自己控制的,使用者可以在 Flutter 的基础上进行无限扩展,而不用受限于系统底层的实现限制
另一方面,这样可以减少 Flutter 在呈现过程中在 Flutter 代码和平台代码之间来回转换,减少了性能瓶颈,提升效率
最后,因为 UI 的实现和底层的操作系统是分离的,所以 Flutter 的 APP 在不同的平台上面可以有统一的外观和实现,可以保证风格的统一
Widgets 表示的是不可变的用户 UI 界面结构;虽然结构是不能够变化的,但是 Widgets 里面的状态是可以动态变化的
根据 Widgets 中是否包含状态,Widgets 可以分为 stateful 和 stateless widget,对应的类是 StatefulWidget 和 StatelessWidget
对于有些 Widgets 来说,比如 icon 或者Label,它里面本身就不需要状态,这些 Widgets 就是 StatelessWidget
但是如果有些 Widgets 中的某些内容可能需要根据用户或者其他原因来动态变化,则就需要使用 StatefulWidget
之前提到了 Widgets 是不可变的,StatefulWidget 中的可变数据是存放在对应的 State 中的,所以 StatefulWidgets 本身并没有 build 方法,所有用户界面都是通过 State 对象来构建的
当 State 发生变化的时候,需要调用 setState() 方法来通知 flutter 框架来调用 State 的 build 方法,从而将变化反馈到用户界面中
至此,我们今天关于 Flutter 框架 中的 Widgets 特性与知识点就介绍到这里了;希望以上的内容能够对大家有所帮助,关于 Flutter 的相关技术问题,我们还要去好好的学习剖析;因此我把工作中遇到的 Flutter 组件开源库相关问题,以及对网上大部分的资料的收集和整理,最终整合出了一份 《Flutter 高级开发学习笔记》
有需要这份学习笔记的朋友,可以 私信 发送 “笔记” 即可 免费获取 希望大家通过阅读这份学习笔记,能够查漏补缺;早日精通 Flutter
内容展示如下:
文章篇幅有限,资料就不做完全展示了;有需要这份 Flutter 高级开发学习笔记 的朋友: 私信 发送 “笔记” 即可 免费获取
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
最后祝各位开发者早日精通 Flutter ,攀登上更高的高峰