1. 简介
什么是 Material Design 和 Material Flutter 库?
Material Design 是一个系统,用于构建醒目、美观的数字产品。通过采用一套一致的原则和组件将样式、品牌、交互和动效结合起来,产品团队能够充分发挥其设计潜能。
Material Flutter 库包含 Flutter 微件(实现 Material Design 组件(简称 MDC),可跨应用和平台打造一致的用户体验。随着 Material Design 体系的发展,这些组件会相应更新,以确保一致的像素级完美实现,并遵循 Google 的前端开发标准。
在此 Codelab 中,您将使用 Material Flutter 的多个组件来构建登录页面。
构建内容
我们提供了 4 个 Codelab 来引导您构建一款名为 Shrine 的应用,这是其中的第 1 个 Codelab。Shrine 是一款销售服饰和家居用品的电子商务应用。它演示了如何使用 Material Flutter 自定义组件以反映任何品牌或样式。
在本 Codelab 中,您将为 Shrine 构建一个包含以下内容的登录页面:
- Shrine 徽标的图片
- 应用名称 (Shrine)
- 两个文本字段,分别用于输入用户名和密码
- 两个按钮
Android | iOS |
此 Codelab 中的 Material Flutter 组件和子系统
- 文本字段
- 按钮
- 墨水涟漪(轻触事件的视觉形式)
您如何评价自己在 Flutter 开发方面的经验水平?
2. 设置您的 Flutter 开发环境
您需要使用两款软件才能完成此 Codelab:Flutter SDK 和一款编辑器。
您可使用以下任一设备学习此 Codelab:
- 一台连接到计算机并设置为开发者模式的实体 Android 或 iOS 设备。
- iOS 模拟器(需要安装 Xcode 工具)。
- Android 模拟器(需要在 Android Studio 中设置)。
- 浏览器(需要使用 Chrome,以便进行调试)。
- 对于 Windows、Linux 或 macOS 桌面应用,您必须在打算部署到的平台上进行开发。因此,如果您要开发 Windows 桌面应用,则必须在 Windows 上进行开发,才能使用相应的构建链。如需详细了解针对各种操作系统的具体要求,请访问 docs.flutter.dev/desktop。
3. 下载 Codelab 起始应用
入门项目位于 material-components-flutter-codelabs-101-starter/mdc_100_series
目录中。
...或从 GitHub 克隆
如需从 GitHub 克隆此 Codelab,请运行以下命令:
git clone https://github.com/material-components/material-components-flutter-codelabs.git cd material-components-flutter-codelabs/mdc_100_series git checkout 101-starter
打开项目并运行应用
- 在您选择的编辑器中打开项目。
- 按照所选编辑器的《使用入门:试驾》中的说明“运行应用”。
大功告成!Shrine 登录页面的起始代码应在您的设备上运行。您应该会看到 Shrine 徽标,并在徽标正下方看到其名称“Shrine”。
Android | iOS |
我们来看一下代码。
login.dart
中的微件
打开 login.dart
。其中应包含以下代码:
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
// TODO: Add text editing controllers (101)
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
children: <Widget>[
const SizedBox(height: 80.0),
Column(
children: <Widget>[
Image.asset('assets/diamond.png'),
const SizedBox(height: 16.0),
const Text('SHRINE'),
],
),
const SizedBox(height: 120.0),
// TODO: Remove filled: true values (103)
// TODO: Add TextField widgets (101)
// TODO: Add button bar (101)
],
),
),
);
}
}
请注意,代码中包含一个 import
语句和两个新类:
import
语句允许在此文件中使用 Material 库。LoginPage
类表示模拟器中显示的整个页面。_LoginPageState
类的build()
函数用于控制界面中所有微件的创建方式。
4. 添加 TextField 微件
首先,我们将在登录页面中添加两个文本字段,供用户输入用户名和密码。我们将使用 TextField 微件,该微件将显示悬浮标签并激活触摸涟漪。
此页面主要采用 ListView 构造,ListView 在可滚动的列中排列其子项。我们来将文本字段放在下面。
添加 TextField 微件
在 const SizedBox(height: 120.0)
后添加两个新的文本字段和一个分隔符。
// TODO: Add TextField widgets (101)
// [Name]
TextField(
decoration: const InputDecoration(
filled: true,
labelText: 'Username',
),
),
// spacer
const SizedBox(height: 12.0),
// [Password]
TextField(
decoration: const InputDecoration(
filled: true,
labelText: 'Password',
),
obscureText: true,
),
每个文本字段都有一个 decoration:
字段,用于获取 InputDecoration 微件。filled:
字段表示文本字段的背景被浅色填充,以帮助用户识别文本字段的点按或触摸目标区域。第二个文本字段的 obscureText: true
值会自动将用户的输入替换为项目符号,适用于输入密码的位置。
保存您的项目(使用按键:command + s),以执行热重载。
您现在应该会看到一个页面,其中包含两个文本字段(“Username”和“Password”)!查看悬浮标签动画:
Android | iOS |
5. 添加按钮
接下来,我们将为登录页面添加两个按钮:“Cancel”和“Next”。我们将使用两种按钮 widget:TextButton 和 ElevatedButton。
添加溢出栏
在文本字段后面,将 OverflowBar
添加到 ListView
的子项:
// TODO: Add button bar (101)
OverflowBar(
alignment: MainAxisAlignment.end,
// TODO: Add a beveled rectangular border to CANCEL (103)
children: <Widget>[
// TODO: Add buttons (101)
],
),
OverflowBar 将其子项排成一行。
添加按钮
然后,向 OverflowBar
的 children
列表添加两个按钮:
// TODO: Add buttons (101)
TextButton(
child: const Text('CANCEL'),
onPressed: () {
// TODO: Clear the text fields (101)
},
),
// TODO: Add an elevation to NEXT (103)
// TODO: Add a beveled rectangular border to NEXT (103)
ElevatedButton(
child: const Text('NEXT'),
onPressed: () {
// TODO: Show the next page (101)
},
),
保存您的项目。在最后一个文本字段下方,您应该会看到两个按钮:
Android | iOS |
OverflowBar
会为您处理布局工作。它会水平放置按钮,使其并排显示。
现在触摸某个按钮会启动水墨涟漪动画,而不会引发其他任何事件。让我们为匿名 onPressed:
函数添加一些功能,使“Cancel”按钮能够清除文本字段,“Next”按钮可以关闭屏幕:
添加 TextEditingControllers
为了能够清除文本字段的值,我们将添加 TextEditingControllers 来控制其文本。
在 _LoginPageState
类的声明的正下方,将控制器添加为 final
变量。
// TODO: Add text editing controllers (101)
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
在第一个文本字段的 controller:
字段中,设置 _usernameController
:
// TODO: Add TextField widgets (101)
// [Name]
TextField(
controller: _usernameController,
在第二个文本字段的 controller:
字段中,设置 _passwordController
:
// TODO: Add TextField widgets (101)
// [Password]
TextField(
controller: _passwordController,
编辑 onPressed
在 TextButton 的 onPressed:
函数中添加用于清除每个控制器的命令:
// TODO: Clear the text fields (101)
_usernameController.clear();
_passwordController.clear();
保存您的项目。现在,当您在文本字段中输入内容时,点击“Cancel”会再次清除每个字段。
此登录表单结构完善!让我们带领用户继续探索 Shrine 应用的其他部分。
弹出
为关闭此视图,我们希望从导航栈中弹出(或删除)此页面(在 Flutter 中称为路由)。
在 ElevatedButton 的 onPressed:
函数中,从导航器中弹出最新路线:
// TODO: Show the next page (101)
Navigator.pop(context);
最后,打开 home.dart
并在 Scaffold
中将 resizeToAvoidBottomInset
设置为 false
:
return Scaffold(
// TODO: Add app bar (102)
// TODO: Add a grid view (102)
body: Center(
child: Text('You did it!'),
),
// TODO: Set resizeToAvoidBottomInset (101)
resizeToAvoidBottomInset: false,
);
这样做可确保键盘的外观不会更改首页或其微件的大小。
大功告成!保存您的项目。继续操作,点击“Next”。
大功告成!
Android | iOS |
此屏幕是我们下一个 Codelab 的起点,您可以在 MDC-102 中继续使用它。
6. 恭喜!
我们添加了文本字段和按钮,并且在过程中几乎不用考虑布局代码。适用于 Flutter 的 Material 组件提供很多样式,几乎可以毫不费力地布局到屏幕上。
后续步骤
文本字段和按钮是 Material 系统的两个核心组件,但该系统还提供了许多其他组件!您还可以在 Material 组件 widget 目录中探索其余内容。
或者,请前往 MDC-102:Material Design 结构和布局,了解 MDC-102 for Flutter 涵盖的组件。