Skip to content

Flutter - Widget 简介

正如架构章节所述,widgets(组件/控件)是任何 Flutter 应用的基础构建块。它们描述了用户界面一部分的配置和状态。Flutter 的 UI 本质上就是一个由 widgets 组成的树形结构。

本章将深入探讨 widget 的概念、类型,并介绍一些基础的、常用 的 widgets。

在 Flutter 中,widget 是用户界面一部分的不可变(immutable)描述。‘不可变’ 意味着一个 widget 的属性(其配置)在创建后不能改变。如果 UI 中的某些部分需要变化,Flutter 会使用配置不同的新 widget 实例来重建 widget 树的相关部分。

Widgets 形成一个层级结构或树。一个 widget 可以包含其他 widgets(其子 widgets),从而创建嵌套结构。例如,一个 Scaffold widget 可能包含一个 AppBar 和一个 Column,而那个 Column 可能包含多个 Text 和 Padding widgets。

每个 widget 都定义了一个 build 方法。当框架需要渲染该 widget 时,就会调用此方法。build 方法接受一个 BuildContext 对象作为参数(该对象提供有关 widget 在树中位置的信息),并且必须返回一个 Widget(或一个 widget 树),该 widget 描述了该部分的 UI。

// Example structure of a StatelessWidget's build method
class MyCustomWidget extends StatelessWidget {
final String message;
const MyCustomWidget({Key? key, required this.message}) : super(key: key);
@override
Widget build(BuildContext context) {
// Returns the widget(s) that make up this custom widget's UI
return Container(
padding: const EdgeInsets.all(16.0),
color: Colors.lightBlueAccent,
child: Text(message), // Uses the 'message' property
);
}
}

当 StatefulWidget 中的状态(state)发生变化时,其 build 方法会再次被调用,以获取更新后的 widget 描述。

Flutter 中的 widgets 可以根据其目的进行分组:

  • 布局 Widgets(Layout Widgets): 帮助排列其他 widgets(例如:Row, Column, Stack, Padding, Center, Container)。在布局章节中讲解。
  • 状态管理 Widgets(State Management Widgets): 主要包括 StatelessWidget 和 StatefulWidget,它们决定了 widget 是否管理内部状态。在架构和状态管理章节中讲解。
  • 平台特定 Widgets(Platform-Specific Widgets): 提供特定平台的外观和感觉:
  • - **Material Widgets:** 实现 Google 的 Material Design 系统(例如:`Scaffold`, `AppBar`, `ElevatedButton`, `TextField`)。常用于 Android 风格的应用。
  • - **Cupertino Widgets:** 实现 Apple 的 Human Interface Guidelines(人机界面指南)(例如:`CupertinoPageScaffold`, `CupertinoNavigationBar`, `CupertinoButton`, `CupertinoTextField`)。常用于 iOS 风格的应用。
  • 基础/平台无关 Widgets(Basic/Platform-Agnostic Widgets): 在不同设计中都使用的核心构建块(例如:Text, Image, Icon, GestureDetector)。
  • 动画与交互 Widgets(Animation & Interaction Widgets): 用于创建动画(AnimatedContainer)或处理特定交互(GestureDetector, Draggable)。

让我们看看一些你将经常使用的基本 widgets。

Text widget 用于显示字符串文本,可选择添加样式。

// Simple Text
const Text('Hello, Flutter Devs!');
// Text with styling
Text(
'Styled Text',
style: TextStyle(
color: Colors.purple,
fontSize: 20.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
letterSpacing: 1.5,
decoration: TextDecoration.underline,
),
);
// Text alignment and overflow handling
Container(
width: 200, // Constrain width to see overflow
child: Text(
'This is a very long line of text that will likely need to wrap or handle overflow.',
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis, // Show '...' if text exceeds maxLines
),
)

style 属性接受一个 TextStyle 对象来控制外观。其他重要属性包括 textAlign(文本对齐)、maxLines(最大行数)和 overflow(溢出处理)。

Text.rich 允许在同一个 widget 中使用 TextSpan 子 widgets 显示包含多种样式的文本:

Text.rich(
TextSpan(
text: 'Normal, ',
style: TextStyle(color: Colors.black),
children: <TextSpan>[
TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ', and '),
TextSpan(text: 'italic.', style: TextStyle(fontStyle: FontStyle.italic, color: Colors.blue)),
],
),
)

Image widget 用于显示图片。它支持使用不同的构造函数从各种来源加载图片:

  • Image.asset: 从项目的 assets 文件夹加载图片。需要在 pubspec.yaml 中配置。

  • Image.network: 从 URL 加载图片。

  • Image.file: 从本地文件路径加载图片(需要访问路径,例如使用 path_provider)。

  • Image.memory: 从原始字节数据(Uint8List)加载图片。

常用属性包括 width(宽度)、height(高度)、fit(图片如何适应其容器,例如 BoxFit.cover, BoxFit.contain)和 alignment(对齐方式)。

Icon widget 用于显示来自字体的图形符号,通常是预捆绑的 Material Icons 字体。

// Basic Icon
const Icon(Icons.favorite, color: Colors.red, size: 30.0);
// Different icon
const Icon(Icons.settings);
// Can be used in buttons, etc.
IconButton(
icon: const Icon(Icons.menu),
tooltip: 'Open navigation menu',
onPressed: () {
// Handle button press
},
)

你需要提供一个 IconData 常量(如 Icons.favorite),并可以自定义 color(颜色)和 size(大小)。

这些是基础的结构性 widgets,尤其对于 Material Design 应用而言:

  • MaterialApp: Material 应用的根 widget。用于配置导航、主题、语言环境(locale)等。
  • Scaffold: 实现了基本的 Material Design 视觉布局结构。提供了显示抽屉(drawers)、SnackBar、底部弹窗(bottom sheets)等的 API,并包含用于放置 AppBar、body、FloatingActionButton、BottomNavigationBar 等的槽位(slots)。
  • AppBar: 通常显示在 Scaffold 顶部的工具栏。包含标题、动作按钮(actions)、前导图标(leading icons)等。

你在简单的 ‘Hello World’ 示例中已经见过它们一起使用了。

本简介仅涵盖了少数核心 widgets。Flutter 框架提供了庞大的 widget 目录,通过组合和自定义它们,你可以构建几乎任何 UI。