MDC-103 Flutter: カラー、シェイプ、高度、タイプによるマテリアルのテーマ設定(Flutter)

logo_components_color_2x_web_96dp.png

マテリアル コンポーネント(MDC)は、デベロッパーがマテリアル デザインを実装する際に役立ちます。Google のエンジニアと UX デザイナーのチームが作成した MDC には、美しく機能的な UI コンポーネントが多数含まれており、Android、iOS、ウェブ、Flutter.material.io/develop で利用できます。

MDC を使用すると、アプリのスタイルをこれまで以上に独自のものにカスタマイズできます。マテリアル デザインの最新の拡張では、デザイナーとデベロッパーが商品のブランドを表現するための柔軟性が向上しています。

Codelab MDC-101 および MDC-102 では、マテリアル コンポーネント(MDC)を使用して、Shrine というアプリの土台を構築しました。Shrine は、衣服と生活雑貨を販売する e コマースアプリです。このアプリのユーザーフローは、最初にログイン画面を表示し、次に商品を表示するホーム画面に移動します。

作成するアプリの概要

この Codelab では、以下を使用して Shrine アプリをカスタマイズします。

  • カラー
  • タイポグラフィ
  • 高度
  • シェイプ
  • レイアウト

7f521db8a762f5ee.png 7ac46e5cb6b1e064.png

この Codelab の MDC-Flutter コンポーネントとサブシステム

  • テーマ
  • タイポグラフィ
  • 高度
  • 画像リスト

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

初心者 中級者 上級者

準備

Flutter でモバイルアプリを開発するには、以下の作業が必要です。

  1. Flutter SDK をダウンロードしてインストールします。
  2. Flutter SDK で PATH を更新します。
  3. Flutter プラグインと Dart プラグインを備えた Android Studio をインストールするか、お好みのエディタをインストールします。
  4. Android Emulator または iOS シミュレータ(Xcode をインストールした Mac が必要)をインストールするか、物理デバイスを使用します。

Flutter のインストールについて詳しくは、スタートガイド: インストールをご覧ください。エディタのセットアップについては、スタートガイド: エディタのセットアップをご覧ください。Android Emulator をインストールする場合は、最新のシステム イメージを搭載した Pixel 3 スマートフォンなどのデフォルトのオプションをご利用になれます。VM アクセラレーションを有効にすることをおすすめしますが、必須ではありません。上記の 4 つの手順を完了したら、Codelab を再開できます。この Codelab を完了するには、1 つのプラットフォーム(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

よくある質問

MDC-102 から続行する場合

MDC-102 が完了済みであれば、コードはこの Codelab を進められる状態になっています。「色を変更する」ステップに進んでください。

ゼロから始める

Codelab のスターター アプリをダウンロードする

スターター アプリをダウンロード

スターター アプリは material-components-flutter-codelabs-103-starter_and_102-complete/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 103-starter_and_102-complete

プロジェクトをセットアップする

これ以降の手順は、Android Studio(IntelliJ)の使用を前提としています。

プロジェクトを開く

1. Android Studio を開きます。

2. ウェルカム画面が表示されたら、[Open an existing Android Studio project] をクリックします。

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'] をクリックします。

Android Studio を再起動します。

スターター アプリを実行する

以下の手順は、Android Emulator または Android デバイスでのテストを前提としていますが、Xcode がインストールされている場合は、iOS シミュレータまたは iOS デバイスでもテストできます。

1. デバイスまたはエミュレータを選択します。Android Emulator がまだ起動していない場合は、[Tools] -> [Android] -> [AVD Manager] を選択し、仮想デバイスを作成してエミュレータを起動します。AVD がすでに存在する場合は、次のステップに示すように、Android Studio のデバイス セレクタから直接エミュレータを起動できます(iOS シミュレータの場合は、まだ起動していなければ、開発マシンで [Flutter Device Selection] -> [Open iOS Simulator] を選択してシミュレータを起動します)。

2. Flutter アプリを起動します。

  • エディタ画面の上部にある [Flutter Device Selection] プルダウン メニューでデバイスを探して選択します(たとえば、<version> 向けにビルドされた Android SDK または iPhone SE など)。
  • 再生アイコン()をクリックします。

正常に完了すると、シミュレータまたはエミュレータに、前の Codelab で作成した Shrine のログインページが表示されます。

Android

iOS

[NEXT] をクリックすると、前の Codelab のホームページが表示されます。

Android

iOS

Shrine のブランドを表すカラーパターンは作成済みです。デザイナーは、Shrine アプリ全体にそのカラーパターンを実装したいと考えています。

最初に、これらのカラーをプロジェクトにインポートしましょう。

colors.dart を作成する

colors.dart という名前の新しい dart ファイルを lib に作成します。マテリアル コンポーネントをインポートして、カラーの const 値を追加します。

import 'package:flutter/material.dart';

const kShrinePink50 = Color(0xFFFEEAE6);
const kShrinePink100 = Color(0xFFFEDBD0);
const kShrinePink300 = Color(0xFFFBB8AC);
const kShrinePink400 = Color(0xFFEAA4A4);

const kShrineBrown900 = Color(0xFF442B2D);

const kShrineErrorRed = Color(0xFFC5032B);

const kShrineSurfaceWhite = Color(0xFFFFFBFA);
const kShrineBackgroundWhite = Colors.white;

カスタムのカラーパレット

このカラーテーマは、デザイナーがカスタムカラーを使って作成したものです(下記の画像を参照)。これには Shrine のブランドから選択されたカラーが含まれており、Material Theme Editor に適用されています。Material Theme Editor では、それらのカラーが拡張され、より完全なパレットが作成されています(これらのカラーは、2014 マテリアル カラーパレットに由来するものではありません)。

Material Theme Editor では、カラーは数字のラベルが付いたシェードに分類され、各カラーのラベルは 50、100、200、....900 となっています。Shrine では、ピンクの見本からの 50、100、300 と、ブラウンの見本からの 900 のシェードのみを使用します。

wlq5aH94SfU47pcalUqOSK57OCX4HnJJTpMVzVrBZreUOE-CrkX2akKrnTbgwf6BQNMBi-nn16jpgQHDeQZixTCeh1A0qTXcxDMTcc2-e6uJg0LPjkXWEVlV7cwS0U1naqpnHToEIQ 1HLdzGp-TIhg2ULijquMw_KQdk18b080CVQN_oECAhiCnFI11Nm3nbcsCIXvZBXULMajAW9NEmGZ7iR_j-eEF6NiODuaike96xVpLwUIzfV4dzTg9uQHsmNG-BDTOd04e6_eRLs--Q

ウィジェットの各カラー パラメータは、これらのパターンのカラーにマッピングされます。たとえば、入力をアクティブに受け取ったときのテキスト フィールドの装飾の色は、テーマのプライマリ カラーになります。その色のアクセシビリティが低い(背景に対して見づらい)場合は、代わりに PrimaryVariant を使用してください。

これらのバリエーションは 2014 年版のマテリアル ガイドライン用に作成されたものですが、現在のガイドライン(カラーシステムの記事)と MDC-Flutter でも引き続き利用できます。これらのバリエーションをコード内で利用するには、ベースカラーに続いてシェード(通常は百単位の値)を呼び出します。たとえば、ピンクの 400 を取得するには、コマンド Colors.pink[400] を使用します。

これらのパレットをデザインとコードに使用すると、完璧な効果が得られます。ブランディングに適したカラーがすでにある場合は、パレット生成ツールまたは Material Theme Editor を使用して、調和のとれたパレットを独自に生成できます。

使用するカラーを決めたので、それらを UI に適用できます。そのためには、ウィジェット階層の最上位にある MaterialApp インスタンスに適用する ThemeData ウィジェットの値を設定します。

ThemeData.light() をカスタマイズする

Flutter には組み込みのテーマがいくつかあります。ライトテーマはそのひとつです。ThemeData ウィジェットをゼロから作成する代わりに、ライトテーマをコピーし、アプリ用にカスタマイズするために値を変更します。

app.dart.colors.dart をインポートします。

import 'colors.dart';

次に、ShrineApp クラスのスコープ外にある app.dart に以下のコードを追加します。

// TODO: Build a Shrine Theme (103)
final ThemeData _kShrineTheme = _buildShrineTheme();

ThemeData _buildShrineTheme() {
  final ThemeData base = ThemeData.light();
  return base.copyWith(
    accentColor: kShrineBrown900,
    primaryColor: kShrinePink100,
    buttonTheme: base.buttonTheme.copyWith(
      buttonColor: kShrinePink100,
      colorScheme: base.colorScheme.copyWith(
        secondary: kShrineBrown900,
      ),
    ),
    buttonBarTheme: base.buttonBarTheme.copyWith(
      buttonTextTheme: ButtonTextTheme.accent,
    ),
    scaffoldBackgroundColor: kShrineBackgroundWhite,
    cardColor: kShrineBackgroundWhite,
    textSelectionColor: kShrinePink100,
    errorColor: kShrineErrorRed,
    // TODO: Add the text themes (103)
    // TODO: Add the icon themes (103)
    // TODO: Decorate the inputs (103)
  );
}

ここで、ShrineApp の build() 関数(MaterialApp ウィジェット内にあります)の末尾に theme: を設定し、新しいテーマを指定します。

  // TODO: Add a theme (103)
  theme: _kShrineTheme, // New code

再生ボタンをクリックします。ログイン画面は次のようになります。

Android

iOS

ホーム画面は次のようになります。

Android

iOS

デザイナーは、色の変更に加えて、使用可能な特定のタイポグラフィも用意してくれています。Flutter の ThemeData には 3 つのテキストテーマがあります。各テキストテーマは、「見出し」や「タイトル」などのテキスト スタイルのコレクションです。アプリでは、いくつかのスタイルを使用し、値の一部を変更します。

テキストテーマをカスタマイズする

プロジェクトにフォントをインポートするため、pubspec.yaml ファイルにフォントを追加する必要があります。

pubspec.yaml の flutter: タグの直後に次のコードを追加します。

  # TODO: Insert Fonts (103)
  fonts:
    - family: Rubik
      fonts:
        - asset: fonts/Rubik-Regular.ttf
        - asset: fonts/Rubik-Medium.ttf
          weight: 500

これで、Rubik フォントにアクセスして使用できます。

pubspec ファイルのトラブルシューティング

上記の宣言を切り取って貼り付けると、pub get の実行時にエラーが発生することがあります。エラーが発生した場合は、行の先頭の空白文字を削除し、スペース 2 個分のインデントを使用して、スペースに置き換えてください。次の行では 2 個のスペースに置き換えます。

fonts:

次の行では 4 個のスペースに置き換えます。

family: Rubik

以降の行も同様に修正します。

Mapping values are not allowed here」というメッセージが表示された場合は、問題がある行のインデントと、その上の行のインデントをチェックします。

login.dart で、Column() 内のコードを次のように変更します。

Column(
  children: <Widget>[
    Image.asset('assets/diamond.png'),
    SizedBox(height: 16.0),
    Text(
      'SHRINE',
      style: Theme.of(context).textTheme.headline5,
    ),
  ],
)

app.dart で、_buildShrineTheme() の後に次のコードを追加します。

// TODO: Build a Shrine Text Theme (103)
TextTheme _buildShrineTextTheme(TextTheme base) {
  return base.copyWith(
    headline5: base.headline5.copyWith(
      fontWeight: FontWeight.w500,
    ),
    headline6: base.headline6.copyWith(
        fontSize: 18.0
    ),
    caption: base.caption.copyWith(
      fontWeight: FontWeight.w400,
      fontSize: 14.0,
    ),
    bodyText1: base.bodyText1.copyWith(
      fontWeight: FontWeight.w500,
      fontSize: 16.0,
    ),
  ).apply(
    fontFamily: 'Rubik',
    displayColor: kShrineBrown900,
    bodyColor: kShrineBrown900,
  );
}

このコードは、TextTheme を受け取って、見出し、タイトル、キャプションの外観を変更します。

このように fontFamily を適用すると、copyWith() で指定されたタイポグラフィ スケール値(見出し、タイトル、キャプション)のみに変更が適用されます。

一部のフォントについては、カスタムの fontWeight を設定します。FontWeight ウィジェットには、百単位の便利な値があります。フォントでは、通常は w500(500 ウェイト)が中程度の太さで、w400 が標準です。

新しいテキストテーマを使用する

errorColor の後の _buildShrineTheme に次のテーマを追加します。

// TODO: Add the text themes (103)

textTheme: _buildShrineTextTheme(base.textTheme),
primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),

停止ボタンをクリックしてから再生ボタンをクリックします。

ログイン画面とホーム画面でテキストの外観が異なっています。一部のテキストでは Rubik フォントが使用され、それ以外のテキストは、黒でも白でもなくブラウンでレンダリングされています。

Android

iOS

アイコンがまだ白のままであることにお気づきでしょうか。これは、アイコンのテーマがそれぞれ異なっているためです。

カスタマイズしたプライマリ アイコンテーマを使用する

_buildShrineTheme() 関数に次のコードを追加します。

    // TODO: Add the icon theme (103)
    primaryIconTheme: base.iconTheme.copyWith(
      color: kShrineBrown900
    ),

再生ボタンをクリックします。

Android

iOS

アプリバーのアイコンがブラウンになりました。

テキストを縮小する

ラベルがやや大きすぎます。

home.dart で、最も内側の列の children: を変更します。

// TODO: Change innermost Column (103)
children: <Widget>[
// TODO: Handle overflowing labels (103)

  Text(
    product == null ? '' : product.name,
    style: theme.textTheme.button,
    softWrap: false,
    overflow: TextOverflow.ellipsis,
    maxLines: 1,
  ),
  SizedBox(height: 4.0),
  Text(
    product == null ? '' : formatter.format(product.price),
    style: theme.textTheme.caption,
  ),
  // End new code
],

テキストを中央揃えにして位置を下げる

ラベルを中央揃えにして、テキストを各画像の下部ではなく、各カードの下部に揃えましょう。

ラベルをメインの軸の終端(下部)に移動し、中央揃えに変更します。

// TODO: Align labels to the bottom and center (103)

  mainAxisAlignment: MainAxisAlignment.end,
  crossAxisAlignment: CrossAxisAlignment.center,

プロジェクトを保存します。

Android

iOS

かなりよくなりましたが、テキストがカードの中央に揃えられていません。

親列の直交軸の配置を変更します。

// TODO: Center items on the card (103)

    crossAxisAlignment: CrossAxisAlignment.center,

プロジェクトを保存します。ホーム画面は次のようになります。

Android

iOS

これで外観が大幅に改善されました。

テキスト フィールドのテーマを設定する

InputDecorationTheme を使用して、テキスト フィールドの装飾にテーマを設定することもできます。

app.dart_buildShrineTheme() メソッドで inputDecorationTheme: 値を指定します。

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  border: OutlineInputBorder(),
),

現在、テキスト フィールドの装飾は filled になっています。これを削除しましょう。filled を削除して inputDecorationTheme を指定すると、テキスト フィールドに枠線付きスタイルが設定されます。

login.dartfilled: true 値を削除します。

// Remove filled: true values (103)
TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    // Removed filled: true
    labelText: 'Username',
  ),
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    // Removed filled: true
    labelText: 'Password',
  ),
  obscureText: true,
),

[Run] メニューの [Flutter Hot Restart] ボタンをクリックします(アプリをゼロから再起動します)。[Username] フィールドがアクティブになっているとき(フィールドに入力中のとき)のログイン画面は次のようになります。

Android

iOS

テキスト フィールドに入力します。装飾とフローティング プレースホルダはプライマリ カラーでレンダリングされます。しかし、それらは簡単には見分けられません。色のコントラストが不明瞭なピクセルを識別しづらい人にとっては、アクセシビリティが低い状態です(詳しくは、マテリアル ガイドラインのカラーに関する記事の「アクセシビリティの高いカラー」をご覧ください)。inputDecorationTheme: 内の focusedBorder: を指定して、テキスト フィールドのアクセント カラーをオーバーライドし、上記のカラーテーマでデザイナーが提供している PrimaryVariant に変更しましょう。

app.dartinputDecorationTheme: の下で、focusedBorder: を指定します。

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  focusedBorder: OutlineInputBorder(
    borderSide: BorderSide(
      width: 2.0,
      color: kShrineBrown900,
    ),
  ),
  border: OutlineInputBorder(),
),

次に、両方のテキスト フィールドの labelStyle プロパティを変更し、デザイナーが提供しているカラーテーマでラベルを色付けします。

login.dart で、両方の TextField ウィジェットの InputDecoration() の下に labelStyle: を追加します。

TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    labelText: 'Username',
    labelStyle: TextStyle(color: Theme.of(context).accentColor),
  ),
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    labelText: 'Password',
    labelStyle: TextStyle(color: Theme.of(context).accentColor),
  ),
),

テキスト フィールドがフォーカスされているときとフォーカスされていないときで異なるラベルスタイルを設定するため、TextField ウィジェットごとに FocusNode を設定し、ウィジェットがフォーカスされているかどうかに基づいて labelStyle を動的なスタイルに変更する条件ロジックを設定します。

login.dart で、テキスト フィールド コントローラの下の _LoginPageState クラスの上部にある FocusNodes とフォーカスされていないラベルの色を初期化しましょう。

class _LoginPageState extends State<LoginPage> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  final _unfocusedColor = Colors.grey[600];
  final _usernameFocusNode = FocusNode();
  final _passwordFocusNode = FocusNode();

initState をオーバーライドして、FocusNodes のリスナーを追加します。

@override
void initState() {
  super.initState();
  _usernameFocusNode.addListener(() {
      setState(() {
        //Redraw so that the username label reflects the focus state
      });
   });
  _passwordFocusNode.addListener(() {
      setState(() {
        //Redraw so that the password label reflects the focus state
      });
   });
}

最後に、TextField ウィジェット内に focusNode: プロパティを追加し、InputDecoration() の下に labelStyle: の条件ロジックを追加します。

TextField(
  controller: _usernameController,
  decoration: InputDecoration(
    labelText: 'Username',
    labelStyle: TextStyle(
        color: _usernameFocusNode.hasFocus
           ? Theme.of(context).accentColor
           : _unfocusedColor),
  ),
  focusNode: _usernameFocusNode,
),
SizedBox(height: 12.0),
TextField(
  controller: _passwordController,
  decoration: InputDecoration(
    labelText: 'Password',
    labelStyle: TextStyle(
        color: _passwordFocusNode.hasFocus
           ? Theme.of(context).accentColor
           : _unfocusedColor),
  ),
  focusNode: _passwordFocusNode,
),

再生ボタンをクリックします。

Android

iOS

ここまでは、Shrine に合った特定の色とタイポグラフィを使用してページのスタイルを設定しました。次は、Shrine の商品を表示するカードを見てみましょう。現在、カードはサイトのナビゲーションの横の白いサーフェス上にあります。

カードの高度を調整する

home.dart で、カードに elevation: 値を追加します。

// TODO: Adjust card heights (103)

    elevation: 0.0,

プロジェクトを保存します。

Android

iOS

カードの下のシャドウが除去されました。

これに合わせて、ログイン画面のコンポーネントの高度を変更しましょう。

[NEXT] ボタンの高度を変更する

RaisedButton のデフォルトの高度は 2 です。もっと高くしましょう。

login.dart で、NEXT RaisedButton に elevation: 値を追加します。

RaisedButton(
  child: Text('NEXT'),
  elevation: 8.0, // New code

[Run] メニューの [Flutter Hot Restart] ボタンをクリックします(アプリをゼロから再起動します)。ログイン画面は次のようになります。

Android

iOS

Shrine には、八角形または四角形のシェイプを持つ要素が定義された、お洒落な幾何学的スタイルがあります。ホーム画面のカードと、ログイン画面のテキスト フィールドおよびボタンに、それらのシェイプのスタイルを実装しましょう。

ログイン画面のテキスト フィールドのシェイプを変更する

app.dart で、隅がカットされた枠線用の特別なファイルをインポートします。

import 'supplemental/cut_corners_border.dart';

引き続き app.dart で、隅がカットされたシェイプをテキスト フィールドの装飾テーマに追加します。

// TODO: Decorate the inputs (103)
inputDecorationTheme: InputDecorationTheme(
  focusedBorder: CutCornersBorder(
    borderSide: BorderSide(
      width: 2.0,
      color: kShrineBrown900,
    ),
  ),
  border: CutCornersBorder(), // Replace code
),

ログイン画面のボタンのシェイプを変更する

login.dart で、[CANCEL] ボタンに斜めの四角形の枠線を追加します。

FlatButton(
  child: Text('CANCEL'),
  shape: BeveledRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(7.0)),
  ),

FlatButton には目に見えるシェイプがないのに、枠線のシェイプを追加するのはなぜでしょうか?それは、タップされたときにリップル アニメーションが同じシェイプに収まるようにするためです。

次に、[NEXT] ボタンに同じシェイプを追加します。

RaisedButton(
  child: Text('NEXT'),
  elevation: 8.0,
  shape: BeveledRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(7.0)),
  ),

すべてのボタンのシェイプを変更するため、app.dartbuttonTheme を更新することもできます。これは学習の課題として取っておきましょう。

[Run] メニューの [Flutter Hot Restart] ボタンをクリックします(アプリをゼロから再起動します)。

Android

iOS

次に、レイアウトを変更して、カードをさまざまなアスペクト比とサイズで表示し、各カードの違いを際立たせましょう。

GridView を AsymmetricView に置き換える

非対称レイアウト用のファイルはすでに作成済みです。

home.dart のファイル全体を次のように変更します。

import 'package:flutter/material.dart';

import 'model/products_repository.dart';
import 'model/product.dart';
import 'supplemental/asymmetric_view.dart';

class HomePage extends StatelessWidget {
  // TODO: Add a variable for Category (104)

  @override
  Widget build(BuildContext context) {
  // TODO: Return an AsymmetricView (104)
  // TODO: Pass Category variable to AsymmetricView (104)
    return Scaffold(
      appBar: AppBar(
        brightness: Brightness.light,
        leading: IconButton(
          icon: Icon(Icons.menu),
          onPressed: () {
            print('Menu button');
          },
        ),
        title: Text('SHRINE'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              print('Search button');
            },
          ),
          IconButton(
            icon: Icon(Icons.tune),
            onPressed: () {
              print('Filter button');
            },
          ),
        ],
      ),
      body: AsymmetricView(products: ProductsRepository.loadProducts(Category.all)),
    );
  }
}

プロジェクトを保存します。

Android

iOS

織物のようなパターンで商品を水平方向にスクロールできるようになりました。また、ステータスバーのテキスト(上部の時刻とネットワークの表示)が黒になりました。これは、AppBar の明るさを明るい brightness: Brightness.light に変更したためです。

色はブランドを表現するための強力な手段です。色を少し変えるだけで、ユーザー エクスペリエンスに大きく影響します。これを試すために、ブランドのカラーパターンをまったく違うものに変更すると Shrine がどのように見えるかを確認してみましょう。

色を変更する

colors.dart に次のコードを追加します。

const kShrinePurple = Color(0xFF5D1049);
const kShrineBlack = Color(0xFF000000);

app.dart_buildShrineTheme() 関数と _buildShrineTextTheme 関数を次のように変更します。

ThemeData _buildShrineTheme() {
  final ThemeData base = ThemeData.light();
  return base.copyWith(
    primaryColor: kShrinePurple,
    buttonTheme: base.buttonTheme.copyWith(
      buttonColor: kShrinePurple,
      textTheme: ButtonTextTheme.primary,
      colorScheme: ColorScheme.light().copyWith(primary: kShrinePurple)
    ),
    scaffoldBackgroundColor: kShrineSurfaceWhite,
    textTheme: _buildShrineTextTheme(base.textTheme),
    primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
    accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
    primaryIconTheme: base.iconTheme.copyWith(
      color: kShrineSurfaceWhite
    ),
    inputDecorationTheme: InputDecorationTheme(
      focusedBorder: CutCornersBorder(
        borderSide: BorderSide(
          width: 2.0,
          color: kShrinePurple,
        ),
      ),
      border: CutCornersBorder(),
    ),
  );
}

TextTheme _buildShrineTextTheme(TextTheme base) {
  return base.copyWith(
    headline5: base.headline5.copyWith(
      fontWeight: FontWeight.w500,
    ),
    headline6: base.headline6.copyWith(
        fontSize: 18.0,
    ),
    caption: base.caption.copyWith(
      fontWeight: FontWeight.w400,
      fontSize: 14.0,
    ),
    bodyText1: base.bodyText1.copyWith(
      fontWeight: FontWeight.w500,
      fontSize: 16.0,
    ),
  ).apply(
    fontFamily: 'Rubik',
  );
}

login.dart で、ロゴのダイヤモンドの色を黒にします。

Image.asset(
  'assets/diamond.png',
  color: kShrineBlack, // New code
),

home.dart で、AppBar の明るさを暗くします。

brightness: Brightness.dark,

プロジェクトを保存します。新しいテーマが表示されます。

Android

iOS

Android

iOS

外観が大きく変わりました。MDC-104 に進む前に、この色に関するコードを元に戻しましょう。

MDC-104 のスターター コードをダウンロード

以上で、デザイナーのデザイン仕様に近いアプリが作成されました。

次のステップ

この Codelab では、MDC コンポーネントとして、テーマ、タイポグラフィ、高度、シェイプを使用しました。MDC-Flutter ライブラリには、もっと多くのコンポーネントとサブシステムがあります。

次は、supplemental ディレクトリにあるファイルを詳しく調べて、水平スクロールが可能な非対称レイアウト グリッドを作成する方法を学習します。

計画しているアプリのデザインの要素に、MDC ライブラリのコンポーネントがない場合はどうしますか?MDC-104: マテリアル デザインの高度なコンポーネントでは、MDC ライブラリを使用して、特定の外観を備えたカスタム コンポーネントを作成する方法を示します。

次の Codelab

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

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

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

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