MDC-101 Flutter:Material Components (MDC) 基础知识 (Flutter)

1. 简介

什么是 Material Design 和 Material Components for Flutter?

Material Design 是一个用于构建亮眼且美观的数字产品的系统。产品团队采用一组一致的原则和组件,统一风格、品牌、交互和动作,可以实现其最大的设计潜力。

Material Components for Flutter (MDC-Flutter) 通过组件库统一设计和工程,在不同应用和平台上打造一致的用户体验。随着 Material Design 系统的发展,这些组件会进行相应更新,以确保一致的像素级完美实现,并遵循 Google 的前端开发标准。MDC 也可用于 Android、iOS 和 Web。

在本 Codelab 中,您将使用 MDC Flutter 的多个组件构建一个登录页面。

您将构建的应用

本 Codelab 是四个 Codelab 中的第一个,将指导您构建一个名为 Shrine 的应用,这是一个销售服饰和家居用品的电子商务应用。本 Codelab 将说明如何自定义组件,以使用 MDC-Flutter 反映任何品牌或风格。

在本 Codelab 中,您将构建 Shrine 的登录页面,其中包含:

  • Shrine 徽标的图像
  • 应用的名称 (Shrine)
  • 两个文本字段,分别用于输入用户名和密码
  • 两个按钮

Android

iOS

本 Codelab 中的 MDC 组件

  • 文本字段
  • 按钮
  • 波纹(对轻触事件的可视形式反馈)

您如何评价您在 Flutter 开发方面的经验?

初级 中级 专家

2. 设置您的 Flutter 环境

准备工作

要开始使用 Flutter 开发移动应用,您需要执行以下操作:

  1. 下载并安装 Flutter SDK。
  2. 更新 PATH 以包含 Flutter SDK。
  3. 安装 Android Studio 并添加 Flutter 和 Dart 插件,或者选择您喜欢的编辑器。
  4. 安装 Android 模拟器、iOS 模拟器(需要装有 Xcode 的 Mac),或者使用实体设备。

如需了解有关 Flutter 安装的详细信息,请参阅 使用入门:安装。要设置编辑器,请参阅 使用入门:设置编辑器。安装 Android 模拟器时,您可以使用默认选项(如 Pixel 3 手机) 并安装最新系统映像。建议启用 VM 加速,但不做强制要求。在完成上述 4 个步骤后,您可以返回到本 Codelab。要完成本 Codelab,您只需要安装适用于其中一个平台(Android 或 iOS) 的 Flutter。

确保 Flutter SDK 处于正确的状态

在继续本 Codelab 之前,请确保您的 SDK 处于正确的状态。如果之前安装了 Flutter SDK,请使用 flutter upgrade 确保 SDK 处于最新状态。

 flutter upgrade

运行 flutter upgrade 会自动运行 flutter doctor。如果这是全新的 Flutter 安装,则无需 升级,手动运行 flutter doctor 即可。它将报告是否存在为完成设置您需安装的任何依赖项。您可以忽略与您无关的对勾标记(例如,如果您不打算针对 iOS 开发,则可以忽略 Xcode)。

 flutter doctor

常见问题解答

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

设置项目

以下说明假定您使用的是 Android Studio (IntelliJ)。

打开项目

1.打开 Android Studio。

2.如果看到欢迎屏幕,请点击 Open an existing Android Studio project(打开现有的 Android Studio 项目)

3.导航至 material-components-flutter-codelabs/mdc_100_series 目录并点击"Open"(打开)。项目应会打开。 在构建项目之前,您可以忽略在 Dart Analysis 中看到的任何错误。

4.如果出现提示:

  • 安装任何平台和插件更新或 FlutterRunConfigurationType。
  • 如果未配置 Dart 或 Flutter SDK,请设置 Flutter 插件的 Flutter SDK 路径
  • 配置 Android 框架。
  • 点击"Get dependencies"(获取依赖项)或"Run ‘flutter packages get'"(运行 ‘flutter packages get')。

然后重新启动 Android Studio。

运行起始应用

以下说明假定您是在 Android 模拟器或设备上进行的测试,但如果您安装了 Xcode,也可以在 iOS 模拟器或设备上测试。

1.选择设备或模拟器。如果 Android 模拟器尚未运行,请选择 Tools(工具)-> Android -> AVD Manager(AVD 管理器)创建虚拟设备,然后启动模拟器。如果 AVD 已存在,您可以直接从 Android Studio 中的设备选择器启动模拟器,如下一步中所示。(对于 iOS 模拟器,如果它尚未运行,则通过选择 Flutter Device Selection(Flutter 设备选择)-> Open iOS Simulator(打开 iOS 模拟器),以在开发机器上启动模拟器。)

2.启动 Flutter 应用:

  • 查看编辑器屏幕顶部的"Flutter Device Selection"(Flutter 设备选择)下拉菜单并选择设备(例如 iPhone SE 或 Android SDK built for <版本>)。
  • 点按 Play(播放)图标 ()。

成功!您的模拟器中现在应该正在运行 Shrine 登录页面的起始代码。您应该会看到 Shrine 徽标,并且在徽标正下方看到名称"Shrine"。

Android

iOS

我们来看一下代码。

login.dart 中的微件

打开 login.dart。其中应包含以下代码:

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  @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: EdgeInsets.symmetric(horizontal: 24.0),
          children: <Widget>[
            SizedBox(height: 80.0),
            Column(
              children: <Widget>[
                Image.asset('assets/diamond.png'),
                SizedBox(height: 16.0),
                Text('SHRINE'),
              ],
            ),
            SizedBox(height: 120.0),
            // TODO: Wrap Username with AccentColorOverride (103)
            // TODO: Remove filled: true values (103)
            // TODO: Wrap Password with AccentColorOverride (103)
            // TODO: Add TextField widgets (101)
            // TODO: Add button bar (101)
          ],
        ),
      ),
    );
  }
}

// TODO: Add AccentColorOverride (103)

请注意,代码中包含一个 import 语句和两个新的类:

  • import 语句用于将 Material Components 引入此文件。
  • LoginPage 类代表模拟器中显示的整个页面。
  • _LoginPageState 类的 build() 函数用于控制界面中所有微件的创建方式。

4. 添加 TextField 微件

首先,我们在登录页面中添加两个文本字段,供用户输入其用户名和密码。我们将使用 TextField 微件,以显示悬浮标签并激活触控波纹。

此页面主要使用 ListView 构造,该视图可以将其子项排列在可滚动列中。我们将文本字段放在底部。

添加 TextField 微件

SizedBox(height: 120.0) 后面新增两个文本字段和一个空格。

// TODO: Add TextField widgets (101)
// [Name]
TextField(
  decoration: InputDecoration(
    filled: true,
    labelText: 'Username',
  ),
),
// spacer
SizedBox(height: 12.0),
// [Password]
TextField(
  decoration: InputDecoration(
    filled: true,
    labelText: 'Password',
  ),
  obscureText: true,
),

每个文本字段都有一个 decoration: 字段,用于获取 InputDecoration 微件。filled: 字段意味着文本字段的背景将用浅色填充,以帮助人们识别文本字段的点按或轻触目标区域。第二个文本字段的 obscureText: true 值会自动将用户的输入替换成项目符号,适合用于掩盖密码。

保存项目(使用按键:command + s)会对项目进行热重载。

您现在应会看到一个包含两个字段(Username 和 Password)的页面!查看悬浮标签动画:

Android

iOS

5. 添加按钮

接下来,我们将在登录页面中添加两个按钮:"Cancel"(取消)和"Next"(下一步)。 我们将使用两种 MDC 按钮微件:FlatButton(在 Material 指南中被称为"文本按钮")和 RaisedButton(称为"实心按钮")。

添加 ButtonBar

在文本字段后面,将 ButtonBar 添加到 ListView 的子项:

// TODO: Add button bar (101)
ButtonBar(
  // TODO: Add a beveled rectangular border to CANCEL (103)
  children: <Widget>[
    // TODO: Add buttons (101)
  ],
),

ButtonBar 会将其子项排成一行。

添加按钮

然后将两个按钮添加到 children 的 ButtonBar 列表中:

    // TODO: Add buttons (101)
    FlatButton(
      child: 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)
    RaisedButton(
      child: Text('NEXT'),
      onPressed: () {
    // TODO: Show the next page (101) 
      },
    ),

保存项目。在最后一个文本字段下方,您应该会看到两个按钮:

Android

iOS

ButtonBar 将为您处理布局工作。它将水平放置按钮,使它们根据当前 ButtonTheme 中的填充并排显示。(请参阅 Codelab MDC-103 了解详情。)

现在轻触按钮只会启动墨纹动画,而不会引发任何其他事件。让我们为匿名 onPressed: 函数添加一些功能,以使"取消"按钮可以清除文本字段,"下一步"按钮可以关闭屏幕:

添加 TextEditingController

为了能够清除文本字段的值,我们将添加 TextEditingController 以控制其文本。

_LoginPageState 类的声明下,将控制器添加为 final 变量。

  // TODO: Add text editing controllers (101)
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

在第一个文本字段的 controller: 字段中,设置 _usernameController

// [Name]
TextField(
  controller: _usernameController,

在第二个文本字段的 controller: 字段中,现在设置 _passwordController

// [Password]
TextField(
  controller: _passwordController,

编辑 onPressed

在 FlatButton 的 onPressed: 函数中添加命令以清除每个控制器:

    // TODO: Clear the text fields (101)
    _usernameController.clear();
    _passwordController.clear();

保存项目。现在,当您在文本字段中输入内容时,再次点击"取消"会清除每个字段。

此登录表现在看上去不错!让我们带用户前进到 Shrine 应用的其余部分。

弹出

为关闭此视图,我们希望此页面(在 Flutter 中称为路由)从导航栈中弹出(也就是移除)。

在 RaisedButton 的 onPressed: 函数中,将最近的路由从 Navigator 中弹出:

        // 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. 全部完成

我们添加了文本字段和按钮,在这个过程中几乎不用考虑布局代码。Material Components for Flutter 拥有很多样式,并且这些样式可以毫不费力地摆放在屏幕上。

后续步骤

文本字段和按钮是 Material System 中的两个核心组件,但该系统还提供了许多其他的组件! 您也可以 在 Flutter 的 Material Components 库中探索其余微件。

或者,前往 MDC-102:Material Design 的结构和布局了解 MDC-102 for Flutter 中所述的组件。

我能够用合理的时间和精力完成此 Codelab

非常赞同 赞同 中立 不赞同 非常不赞同

我未来会继续使用 Material Components

非常赞同 赞同 中立 不赞同 非常不赞同