Widget
要开始使用 Flutter,你需要对 Dart 编程语言(Flutter 应用是用它编写的)和 Widget(Flutter UI 的构建块)有一定的了解。本页将介绍两者,但你将在本系列中继续学习它们。本页列出了其他资源,但你不必成为这两个主题的专家才能继续学习。
Widget
#关于 Flutter,你经常会听到“一切皆为 Widget”。Widget 是 Flutter 应用用户界面的构建块,每个 Widget 都是用户界面一部分的不可变声明。Widget 用于描述用户界面的所有方面,包括文本和按钮等物理方面以及填充和对齐等布局效果。
Widget 基于组合形成层次结构。每个 Widget 都嵌套在其父 Widget 内,并可以从父 Widget 接收上下文。这种结构一直延续到根 Widget,如下面的简单示例所示:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp( // 根 Widget
home: Scaffold(
appBar: AppBar(
title: const Text('我的主页'),
),
body: Center(
child: Builder(
builder: (context) {
return Column(
children: [
const Text('Hello, World!'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Click!');
},
child: const Text('一个按钮'),
),
],
);
},
),
),
),
);
}
}
在前面的代码中,所有实例化的类都是 Widget:MaterialApp
、Scaffold
、AppBar
、Text
、Center
、Builder
、Column
、SizedBox
和 ElevatedButton
。
Widget 组合
#如前所述,Flutter 强调 Widget 作为组合的单元。Widget 通常由许多其他小型、单一用途的 Widget 组成,这些 Widget 组合在一起可以产生强大的效果。
有一些布局 Widget,例如 Padding
、Alignment
、Row
、Column
和 Grid
。这些布局 Widget 本身没有可视化表示。相反,它们的唯一目的是控制另一个 Widget 布局的某些方面。Flutter 还包含利用这种组合方法的实用程序 Widget。例如,常用的 Widget Container
由几个负责布局、绘制、定位和大小的 Widget 组成。有些 Widget 具有可视化表示,例如前面示例中的 ElevatedButton
和 Text
,以及 Icon
和 Image
等 Widget。
如果你运行前面示例中的代码,Flutter 将绘制一个带有文本“Hello, World!”的按钮,该按钮居中显示在屏幕上,垂直排列。为了定位这些元素,有一个 Center
Widget,它将它的子元素定位在可用空间的中心,还有一个 Column
Widget,它将它的子元素垂直排列在一起。
![显示 Widget 组合的图表,包含一系列线条和节点。](/assets/images/docs/fwe/simple_composition_example.png)
在本系列的下一页中,你将学习更多关于 Flutter 中布局的知识。
构建 Widget
#要在 Flutter 中创建用户界面,你必须重写 Widget 对象上的 build
方法。所有 Widget 都必须具有 build
方法,并且必须返回另一个 Widget。例如,如果你想在屏幕上添加带有一些填充的文本,你可以这样编写:
class PaddedText extends StatelessWidget {
const PaddedText({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: const Text('Hello, World!'),
);
}
}
当创建此 Widget 时以及当此 Widget 的依赖项更改时(例如传递到 Widget 中的状态),框架会调用 build
方法。此方法可能会在每一帧中被调用,并且除了构建 Widget 之外不应有任何副作用。要了解有关 Flutter 如何渲染 Widget 的更多信息,请查看Flutter 架构概述。
Widget 状态
#框架引入了两种主要的 Widget 类:有状态 Widget 和无状态 Widget。
没有可变状态的 Widget(它们没有随时间变化的类属性)是 StatelessWidget
的子类。许多内置 Widget 都是无状态的,例如 Padding
、Text
和 Icon
。当你创建自己的 Widget 时,你大部分时间都会创建 Stateless
Widget。
另一方面,如果 Widget 的独特特性需要根据用户交互或其他因素而改变,则该 Widget 是有状态的。例如,如果一个 Widget 有一个计数器,每当用户点击一个按钮时,计数器就会递增,那么计数器的值就是该 Widget 的状态。当该值发生变化时,需要重建 Widget 以更新其 UI 部分。这些 Widget 是 StatefulWidget
的子类,并且(因为 Widget 本身是不可变的),它们在一个单独的类中存储可变状态,该类是 State
的子类。StatefulWidgets
没有 build
方法;相反,它们的 UI 是通过它们的 State
对象构建的,如下面的示例所示。
class CounterWidget extends StatefulWidget {
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Text('$_counter');
}
}
每当你改变 State
对象(例如,通过递增计数器)时,你必须调用 setState
来向框架发出信号,以通过再次调用 State
的 build
方法来更新用户界面。
将状态与 Widget 对象分离,使其他 Widget 能够以完全相同的方式处理无状态 Widget 和有状态 Widget,而无需担心丢失状态。父 Widget 不需要保留子 Widget 来保存其状态,而可以在任何时候创建子 Widget 的新实例,而不会丢失子 Widget 的持久状态。框架会完成在适当的时候查找和重用现有状态对象的所有工作。
在本系列后面的状态管理课程中,将有更多关于StatefulWidget
对象的信息。
重要的 Widget
#Flutter SDK 包含许多内置 Widget,从最小的 UI 片段(如 Text
)到布局 Widget,以及样式化应用程序的 Widget。在学习路径中的下一课中,以下 Widget 最重要:
下一步:布局
#本页介绍了 Flutter 的基础概念,例如 Widget,并帮助你熟悉阅读 Flutter 和 Dart 代码。如果你对遇到的每个主题都不清楚,也没关系,因为接下来的每一页都会深入探讨特定主题。在下一节中,你将通过在 Flutter 中创建更复杂的布局来开始构建更有趣的 UI。
如果你想练习本页中学习到的信息,你可以阅读使用 Flutter 构建用户界面。
反馈
#由于本网站的这一部分正在不断发展,我们欢迎您的反馈!
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。