什么是 Widget

Flutter 的 Widget 的设计灵感来自于 React,主要目的就是使用 Widget 构建 UI。Widget 根据其当前配置和状态来描述视图,当 Widget 的状态发生更改时,Widget 会重建其描述。framework 将根据前面的描述进行对比,以确定底层渲染树从一个状态转换到下一个状态所需的最小更改。
在 Flutter 中,除了 Basics 的文本、图片、卡片、输入框这些基础控件,布局方式和动画等也都是由 Widget 组成的。通过使用不同类型的 Widget,就可以实现复杂的界面。
Widget 可以翻译为部件,粗略的相当于 Android 中的 View。Widget 和 View 不同的是:Widget 具有不同的生命周期:它是不可变的,每当 Widget 或者其状态发生变化时,Flutter 的框架都会创建一个新的 Widget 实例树。相比之下,Android 中的 View 会被绘制一次,并且在 invalidate 调用之前不会重绘。

Widget 的分类

Widget 的分类有很多类别,每个类别下面又包含很多 Widget,主要包括以下几种类别:

  • Basics:在构建第一个 Flutter 应用程序之前,需要知道的 Basics Widget。
  • Material Components:Material Design 风格的 Widget。
  • Cupertino:iOS 风格的 Widget。
  • Accessibility:辅助功能 Widget。
  • Animation and Motion:动画和动作 Widget。
  • Async:Flutter 应用程序的异步 Widget。
  • Input:除了在 Material Components 和 Cupertino 中的输入 Widget 外,还可以接受用户输入的 Widget。
  • Interaction Models:响应触摸事件并将用户路由到不同的视图中。
  • Layout:用于布局的 Widget。
  • Painting and effects:不改变布局、大小、位置的情况下为子 Widget 应用视觉效果。
  • Scrolling:滚动相关的 Widget。
  • Styling:主题、填充相关 Widget。
  • Text:显示文本和文本样式。

Basics 有些特殊,它是由 Flutter 官方从其他的 Widget 分类中选取的一些 Widget 组成的,这些 Widget 是官方建议开发者构建第一个 Flutter 应用程序之前,需要知道的,目的是让开发者更快的入门。比如 Row 属于 Layout 分类,它就被选进了 Basics 中。本文遵循了 Flutter 官方的意图,首先介绍 Basics (Basics Widget)。

Widget 更多的是以组合的形式存在,比如 Container 是属于 Layout 中的一个 Widget,而 Container 又由 LimitedBox、 ConstrainedBox、Align、 Padding、 DecoratedBox、Transform 部件组成。 如果要实现 Container 的自定义效果,可以组合上面这些 Widget 以及其他简单的 Widget,而不是将 Container 进行子类化实现。

Widget 的状态分类

在 Android 中,我们可以通过直接更改 View 来更新视图。但是在 Flutter 中,Widget 是不可变的并且不会直接更新,而是必须使用 Widget 的状态。
Widget 有两种状态分类分别是无状态的 StatelessWidget 和有状态的 StatefulWidget,StatelessWidget 是不可变的,设置以后就不可再变化,所有的值都是最终的设置。StatefulWidget 可以保存自己的状态,但是 Widget 是不可变的,因此需要配合 State 来保存状态。
State 拥有自己的声明周期,如下所示:

名称 状态
initState create 之后被 insert 到渲染树时调用的,只会调用一次
didChangeDependencies state 依赖的对象发生变化时调用
didUpdateWidget Widget 状态改变时候调用,可能会调用多次
build 构建 Widget 时调用
deactivate 当移除渲染树的时调用
dispose Widget 即将销毁时调用

根 Widget 的种类

  1. void main() => runApp(MyApp());
  2. class MyApp extends StatelessWidget {
  3. @override
  4. Widget build(BuildContext context) {
  5. return MaterialApp(
  6. home: Scaffold(
  7. appBar: AppBar(
  8. title: Text('hello Flutter'),
  9. ),
  10. body: HomeContent(),
  11. ),
  12. theme: ThemeData(
  13. primaryColor: Colors.pink,
  14. ),
  15. );
  16. }
  17. }

上面的 MaterialApp 就是一个根 Widget,也就是 Flutter 应用程序的第一个 Widget,根 Widget 有以下几种:

  • WidgetsApp: 如果需要自定义风格,可以使用 WidgetsApp。
  • MaterialApp:Material Design 风格的 Widget。
  • CupertinoApp iOS 风格的根 Widget。

如果公司没有特殊要求,这里建议使用 MaterialApp 做为根 Widget 就可以了。

Basics Widget

Basics Widget 也就是 Basics,主要有以下几种:

  • Container:一个便利的容器 Widget,可以设置 Widget 的背景、尺寸、定位。
  • Row:在水平方向上布置子窗口 Widget 列表。
  • Column:在垂直方向上布置子窗口 Widge 列表。
  • Image:显示图像的 Widget
  • Text:单一样式的文本。
  • Icon:符合 Material Design 设计规范的图标
  • RaisedButton:符合 Material Design 设计规范的凸起按钮。
  • Scaffold:实现 Basics 的 Material Design 布局结构。
  • Appbar:Material Design 的应用栏。
  • FlutterLogo:以 Widget 形式来展示一个 Flutter 图标,可以调整样式。
  • Placeholder:绘制一个框,为将来添加的 Widget 的占位。