1. はじめに
マテリアル デザインとマテリアル Flutter ライブラリとは何ですか?
マテリアル デザインは、人の目に留まる美しいデジタル プロダクトを作成するためのシステムです。一貫した一連の基本原則とコンポーネントに基づいてスタイル、ブランディング、インタラクション、モーションの統一を行うことにより、プロダクト チームは、デザインの可能性を最大限に発揮できます。
マテリアル Flutter ライブラリには、マテリアル デザイン コンポーネント(略して MDC)のデザインを実装し、アプリとプラットフォーム全体で一貫したユーザー エクスペリエンスを実現する Flutter ウィジェットが含まれています。マテリアル デザイン システムの進化に伴って、これらのコンポーネントは、Google のフロントエンド開発標準に準拠した一貫したピクセル パーフェクトな実装を実現するために更新されます。
この Codelab では、マテリアル Flutter のコンポーネントを使用してログインページを作成します。
作業内容
この Codelab は、衣類や生活雑貨を販売する e コマースアプリ Shrine の作成手順を説明する 4 つの Codelab のうちの最初の Codelab です。マテリアル Flutter を使用してコンポーネントをカスタマイズし、ブランドやスタイルを反映する方法を紹介します。
この Codelab では、次のもの含む Shrine 用ログインページを作成します。
- Shrine のロゴ画像
- アプリ名「Shrine」
- テキスト フィールド 2 つ(ユーザー名用とパスワード用)
- ボタン 2 つ
Android | iOS |
この Codelab で Flutter のコンポーネントとサブシステムをマテリアルにする
- テキスト フィールド
- ボタン
- インクの波紋(タッチイベントに対する視覚的なフィードバック)
Flutter 開発のご経験についてお答えください。
2. Flutter の開発環境をセットアップする
このラボを完了するには、Flutter SDK とエディタの 2 つのソフトウェアが必要です。
この Codelab は、次のいずれかのデバイスを使って実行できます。
- パソコンに接続され、デベロッパー モードに設定された物理デバイス(Android または iOS)
- iOS シミュレータ(Xcode ツールのインストールが必要)
- Android Emulator(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
プロジェクトを開いてアプリを実行する
- お使いのエディタでプロジェクトを開きます。
- エディタで 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 つのボタンを追加します。TextButton と ElevatedButton の 2 種類のボタン ウィジェットを使用します。
オーバーフロー バーを追加する
テキスト フィールドの後、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
のリストにボタンを 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
を開き、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 |
この画面は、MDC-102 で取り組む次の Codelab の出発点となります。
6. 完了
テキスト フィールドとボタンを追加しましたが、レイアウト コードを考慮する必要はほとんどありませんでした。Flutter のマテリアル コンポーネントには多くのスタイルがあり、かなり簡単に画面上に配置できます。
次のステップ
テキスト フィールドとボタンはマテリアル システムの 2 つのコア コンポーネントですが、他にもたくさんあります。残りはマテリアル コンポーネント ウィジェット カタログで確認することもできます。
Flutter の MDC-102 の対象となるコンポーネントについては、MDC-102: マテリアル デザインの構造とレイアウトをご覧ください。