MDC-101 Flutter: マテリアル コンポーネントの基本

1. はじめに

マテリアル デザインとマテリアル Flutter ライブラリとは何ですか?

マテリアル デザインは、人の目に留まる美しいデジタル プロダクトを作成するためのシステムです。一貫した一連の基本原則とコンポーネントに基づいてスタイル、ブランディング、インタラクション、モーションの統一を行うことにより、プロダクト チームは、デザインの可能性を最大限に発揮できます。

マテリアル Flutter ライブラリには、マテリアル デザイン コンポーネント(略して MDC)のデザインを実装し、アプリとプラットフォーム全体で一貫したユーザー エクスペリエンスを実現する Flutter ウィジェットが含まれています。マテリアル デザイン システムの進化に伴って、これらのコンポーネントは、Google のフロントエンド開発標準に準拠した一貫したピクセル パーフェクトな実装を実現するために更新されます。

この Codelab では、マテリアル Flutter のコンポーネントを使用してログインページを作成します。

作業内容

この Codelab は、衣類や生活雑貨を販売する e コマースアプリ Shrine の作成手順を説明する 4 つの Codelab のうちの最初の Codelab です。マテリアル Flutter を使用してコンポーネントをカスタマイズし、ブランドやスタイルを反映する方法を紹介します。

この Codelab では、次のもの含む Shrine 用ログインページを作成します。

  • Shrine のロゴ画像
  • アプリ名「Shrine」
  • テキスト フィールド 2 つ(ユーザー名用とパスワード用)
  • ボタン 2 つ

Android

iOS

Android 上の神社ログインページ

iOS の神社ログインページ

この Codelab で Flutter のコンポーネントとサブシステムをマテリアルにする

  • テキスト フィールド
  • ボタン
  • インクの波紋(タッチイベントに対する視覚的なフィードバック)

Flutter 開発のご経験についてお答えください。

初心者 中級者 上級者

2. Flutter の開発環境をセットアップする

このラボを完了するには、Flutter SDKエディタの 2 つのソフトウェアが必要です。

この Codelab は、次のいずれかのデバイスを使って実行できます。

  • パソコンに接続され、デベロッパー モードに設定された物理デバイス(Android または iOS
  • iOS シミュレータ(Xcode ツールのインストールが必要)
  • Android Emulator(Android Studio でセットアップが必要)
  • ブラウザ(デバッグには Chrome が必要)
  • WindowsLinuxmacOS のデスクトップ アプリケーション。開発はデプロイする予定のプラットフォームで行う必要があります。たとえば、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

プロジェクトを開いてアプリを実行する

  1. お使いのエディタでプロジェクトを開きます。
  2. エディタで Get Started: Test drive を開き、「Run the app」セクションの指示に従います。

完了しました。使用するには、Shin's ログインページのスターター コードがデバイスで実行されている必要があります。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 ステートメントと 2 つの新しいクラスが含まれています。

  • import ステートメントを使用すると、このファイルにマテリアル ライブラリを使用できます。
  • LoginPage クラスは、シミュレータに表示されるページ全体を表します。
  • _LoginPageState クラスの build() 関数は、UI 内のすべてのウィジェットを作成する方法を制御します。

4. TextField ウィジェットを追加する

まず、ログインページにテキスト フィールドを 2 つ追加して、ユーザーがユーザー名とパスワードを入力できるようにします。フローティング ラベルを表示してタッチリップルをアクティブにする、TextField ウィジェットを使用します。

このページは主に、スクロール可能な列に子を配置する ListView で構成されています。テキスト フィールドを以下に表示しましょう。

TextField ウィジェットを追加する

const SizedBox(height: 120.0) の後に、2 つの新しいテキスト フィールドとスペーサーを追加します。

// 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,
),

各テキスト フィールドには、InputDecoration ウィジェットを受け取る decoration: フィールドがあります。filled: フィールドは、テキスト フィールドのタップ ターゲット エリアを認識しやすくするために、テキスト フィールドの背景が薄く塗りつぶされていることを意味します。2 つ目のテキスト フィールドの obscureText: true 値は、ユーザーが入力した内容を自動的に点に置き換えます。これはパスワードに適しています。

ホットリロードを実行するプロジェクトを保存します(キー入力: Command+S キー)。

これで、「Username」と「Password」という 2 つのテキスト フィールドを備えたページが表示されます。フローティング ラベルのアニメーションを確認します。

Android

iOS

ユーザー名とパスワードのフィールドを含む神社のロゴ

ユーザー名とパスワードのフィールドを含む神社のロゴ

5. ボタンを追加する

次に、ログインページに「Cancel」と「Next」という 2 つのボタンを追加します。TextButtonElevatedButton の 2 種類のボタン ウィジェットを使用します。

オーバーフロー バーを追加する

テキスト フィールドの後、OverflowBarListView の子に追加します。

// 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 は、その子を並べます。

ボタンを追加する

次に、OverflowBarchildren のリストにボタンを 2 つ追加します。

    // 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)
      },
    ),

プロジェクトを保存します。最後のテキスト フィールドの下に、ボタンが 2 つ表示されます。

Android

iOS

ユーザー名とパスワードのフィールド、キャンセル ボタン、「次へ」ボタンを含む神社のロゴ

ユーザー名とパスワードのフィールド、キャンセル ボタン、「次へ」ボタンを含む神社のロゴ

OverflowBar はレイアウト処理を自動的に行います。ボタンが横並びになるように配置されます。

ボタンをタップすると、他に何も発生させずにインクの波紋のアニメーションが開始されます。CANCEL ボタンでテキスト フィールドをクリアし、NEXT ボタンで画面を閉じるように、匿名の onPressed: 関数に機能を追加してみましょう。

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,

2 つ目のテキスト フィールドの 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 を開き、ScaffoldresizeToAvoidBottomInsetfalse に設定します。

    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

[完了] と表示された画面

[完了] と表示された画面

この画面は、MDC-102 で取り組む次の Codelab の出発点となります。

6. 完了

テキスト フィールドとボタンを追加しましたが、レイアウト コードを考慮する必要はほとんどありませんでした。Flutter のマテリアル コンポーネントには多くのスタイルがあり、かなり簡単に画面上に配置できます。

次のステップ

テキスト フィールドとボタンはマテリアル システムの 2 つのコア コンポーネントですが、他にもたくさんあります。残りはマテリアル コンポーネント ウィジェット カタログで確認することもできます。

Flutter の MDC-102 の対象となるコンポーネントについては、MDC-102: マテリアル デザインの構造とレイアウトをご覧ください。

この Codelab を完了するためにそれなりの時間と労力を必要とした

非常にそう思う そう思う どちらとも言えない そう思わない まったくそう思わない

今後もマテリアル コンポーネントを使用したい

非常にそう思う そう思う どちらとも言えない そう思わない まったくそう思わない