Posts Enable Google Page Views
Post
Cancel

Enable Google Page Views

本文是『 深入浅出 Flutter Framework 』系列文章的第一篇,主要以不同类型 Widget 的核心方法为切入点,对其展开详细分析。

©原创文章,转载请注明出处!

Overview


Flutter 作为一种新兴跨平台解决方案,自 2017 年 Google 在 I/O 大会上推出后,尤其是在 2018 年 I/O 大会上发布第一个预览版后,迅速引起移动开发者的广泛关注,并成为时下最热门的跨平台解决方案 ( 没有之一 ) !

本系列文章将深入 Flutter Framework 内部逐步去分析其核心概念和流程,主要包括: 『 深入浅出 Flutter Framework 之 Widget 』 『 深入浅出 Flutter Framework 之 BuildOwner 』 『 深入浅出 Flutter Framework 之 Element 』 『 深入浅出 Flutter Framework 之 PaintingContext 』 『 深入浅出 Flutter Framework 之 Layer 』 『 深入浅出 Flutter Framework 之 PipelineOwner 』 『 深入浅出 Flutter Framework 之 RenderObejct 』 『 深入浅出 Flutter Framework 之 Binding 』 『 深入浅出 Flutter Framework 之 Rendering Pipeline 』 『 深入浅出 Flutter Framework 之 自定义 Widget 』

其中,前 7 篇属于基础篇,分别介绍 Flutter 中几个最核心的概念。Rendering Pipeline 篇则是在此基础上从 Build、Layout 到 Paint 的流程将它们串起来,分析 Flutter UI 是如何创建的、如何更新的。最后,自定义 Widget 属于回顾、实践篇,分析自定义一个 Render Widget 至少需要哪些步骤。

下图所示,Flutter 整体分为三层:Framework (dart)、Engine (C/C++)、Embedder (Platform),上述文章主要集中在 Framework 这一层。 img

Widget


Everything’s a widget.

在开发 Flutter 应用过程中,接触最多的无疑就是Widget,是『描述』 Flutter UI 的基本单元,通过Widget可以做到:

  • 描述 UI 的层级结构 (通过Widget嵌套);
  • 定制 UI 的具体样式 (如:fontcolor等);
  • 指导 UI 的布局过程 (如:paddingcenter等);

Google 在设计Widget时,还赋予它一些鲜明的特点:

  • 声明式 UI —— 相对于传统 Native 开发中的命令式 UI,声明式 UI 有不少优势,如:开发效率显著提升、UI 可维护性明显加强等;
  • 不可变性 —— Flutter 中所有Widget都是不可变的(immutable),即其内部成员都是不可变的(final),对于变化的部分需要通过「Stateful Widget-State」的方式实现;
  • 组合大于继承 —— Widget设计遵循组合大于继承这一优秀的设计理念,通过将多个功能相对单一的Widget组合起来便可得到功能相对复杂的Widget

Widget类定义处有这样一段注释: img 这段注释阐明了Widget的本质:用于配置Element的,Widget本质上是 UI 的配置信息 (附带部分业务逻辑)。

我们通常会将通过Widget描述的 UI 层级结构称之为「Widget Tree」,但与「Element Tree」、「RenderObject Tree」以及「Layer Tree」相比,实质上并不存在「Widget Tree」。为了描述方便,将 Widget 组合描述的 UI 层级结构称之为「Widget Tree」,也未尝不可。

分类

img 如上图所示,按照功能划分Widget大致可以分为 3 类:

  • 「Component Widget」 —— 组合类 Widget,这类 Widget 都直接或间接继承于StatelessWidgetStatefulWidget,上一小节提到过在 Widget 设计上遵循组合大于继承的原则,通过组合功能相对单一的 Widget 可以得到功能更为复杂的 Widget。平常的业务开发主要是在开发这一类型的 Widget;
  • 「Proxy Widget」 —— 代理类 Widget,正如其名,「Proxy Widget」本身并不涉及 Widget 内部逻辑,只是为「Child Widget」提供一些附加的中间功能。典型的如:InheritedWidget用于在「Descendant Widgets」间传递共享信息、ParentDataWidget用于配置「Descendant Renderer Widget」的布局信息;
  • 「Renderer Widget」 —— 渲染类 Widget,是最核心的Widget类型,会直接参与后面的「Layout」、「Paint」流程,无论是「Component Widget」还是「Proxy Widget」最终都会映射到「Renderer Widget」上,否则将无法被绘制到屏幕上。这 3 类 Widget 中,只有「Renderer Widget」有与之一一对应的「Render Object」
This post is licensed under CC BY 4.0 by the author.