MDC-104 Android: マテリアルの高度なコンポーネント(Java)

logo_components_color_2x_web_96dp.png

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

material.io/develop

Codelab MDC-103 では、アプリのスタイルを設定するマテリアル コンポーネント(MDC)のカラー、高度、タイポグラフィをカスタマイズしました。

マテリアル デザイン システムのコンポーネントは、事前定義されたタスクのセットを実行します。また、ボタンなど、特定の特性を持っています。ボタンは単にユーザーがアクションを実行するための手段であるだけでなく、形状、サイズ、色を備えた視覚的表現でもあり、UI が操作可能であることと、タップまたはクリックすると何かが起こることをユーザーに伝えます。

マテリアル デザイン ガイドラインは、デザイナーの観点から見たコンポーネントの記述です。複数のプラットフォームで利用できるさまざまな基本機能と、各コンポーネントを構成する微細な要素について説明しています。たとえば、背景(バックドロップ)には、バックレイヤとそのコンテンツ、フロントレイヤとそのコンテンツ、モーション ルール、表示オプションが含まれます。それぞれのコンポーネントは、アプリのニーズ、ユースケース、コンテンツに合わせてカスタマイズできます。そうしたコンポーネントの大半は、プラットフォームの SDK に含まれる従来のビュー、コントロール、関数に対応しています。

マテリアル デザイン ガイドラインには多くのコンポーネントが記載されていますが、一部のコンポーネントは再利用可能なコードでの利用に適しておらず、そのため MDC に含まれていません。従来のコードのみを使用して、そのようなエクスペリエンスを独自に作成し、アプリ用にカスタマイズしたスタイルを実現できます。

作成するアプリの概要

この Codelab では、Shrine に背景を追加します。非対称グリッドに表示される商品をカテゴリでフィルタします。使用するものは次のとおりです。

  • 図形
  • モーション
  • 従来の Android SDK クラス

この Codelab の MDC-Android コンポーネント

  • 図形

必要なもの

  • Android 開発に関する基本的な知識
  • Android Studio (まだお持ちでない場合はこちらからダウンロードしてください)
  • Android Emulator または Android デバイス(Android Studio から入手可能)
  • サンプルコード(次の手順を参照)

Android アプリ作成のご経験についてお答えください。

初心者 中級者 上級者

MDC-103 から続行する場合

MDC-103 が完了済みであれば、コードはこの Codelab を進められる状態になっています。手順 3 に進みます。

ゼロから始める

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

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

スターター アプリは material-components-android-codelabs-104-starter/java ディレクトリにあります。開始する前に、必ずそのディレクトリに cd してください。

GitHub からクローンを作成する

GitHub からこの Codelab のクローンを作成するには、次のコマンドを実行します。

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 104-starter

Android Studio にスターター コードを読み込む

  1. 設定ウィザードが終了し、[Welcome to Android Studio] ウィンドウが表示されたら、[Open an existing Android Studio project] をクリックします。サンプルコードをインストールしたディレクトリに移動し、[java -> shrine](または、パソコンで shrine を検索)を選択して、Shrine プロジェクトを開きます。
  2. Android Studio がプロジェクトをビルドして同期するまで待ちます。進捗状況は、Android Studio ウィンドウ下部のアクティビティ インジケーターに表示されます。
  3. この時点では、Android SDK やビルドツール(以下に示すものなど)が不足しているため、Android Studio でビルドエラーが発生する場合があります。Android Studio の指示に従って、それをインストール/更新して、プロジェクトを同期させます。

プロジェクトの依存関係を追加する

プロジェクトには、MDC Android サポート ライブラリへの依存関係が必要です。ダウンロードしたサンプルコードにはこの依存関係がすでにリストされているはずですが、次の手順で確認することをおすすめします。

  1. app モジュールの build.gradle ファイルに移動し、MDC Android への依存関係が dependencies ブロックに含まれていることを確認します。
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (省略可)必要に応じて、build.gradle ファイルを編集して次の依存関係を追加し、プロジェクトを同期します。
dependencies {
    api 'com.google.android.material:material:1.1.0-alpha06'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}

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

  1. [実行 / 再生ボタン] の左側にあるビルド構成が app であることを確認します。
  2. 緑色の [Run / Play] ボタンを押して、アプリをビルドし実行します。
  3. [Select Deployment Target] ウィンドウで、利用可能なデバイスのリストの中にすでにAndroid デバイスがある場合は、ステップ 8 に進みます。それ以外の場合は、[Create New Virtual Device] をクリックします。
  4. [Select Hardware] 画面で Google Pixel 2 などのスマートフォンを選択し、[Next] をクリックします。
  5. [System Image] 画面で、最新の Android バージョン(可能であれば API レベルが最も高いもの)を選択します。インストールされていない場合は、表示される [Download] をクリックして、ダウンロードを完了します。
  6. [Next] をクリックします。
  7. [Android Virtual Device (AVD)] 画面で、設定をそのまま変更せずに、[Finish] をクリックします。
  8. デプロイ ターゲットのダイアログで Android デバイスを選択します。
  9. [OK] をクリックします。
  10. Android Studio によってアプリがビルドおよびデプロイされ、対象デバイスでそのアプリが自動的に開きます。

完了しました。デバイスで Shrine アプリが実行されているはずです。

背景は、アプリの最も奥にあるサーフェスで、他のすべてのコンテンツとコンポーネントの背後に表示されます。背景は、バックレイヤ(アクションとフィルタを表示)とフロントレイヤ(コンテンツを表示)の 2 つのサーフェスで構成されます。背景を使用して、ナビゲーションやコンテンツ フィルタなどのインタラクティブな情報とアクションを表示できます。

グリッドのコンテンツを隠す

shr_product_grid_fragment.xml で、NestedScrollViewandroid:visibility="gone" 属性を追加して、商品コンテンツを一時的に削除します。

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   android:visibility="gone"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

このリージョンに背景をインストールします。トップ アプリバーと、バックドロップに表示されるメニュー コンテンツの間に区切り線が表示されないように、バックドロップをトップ アプリバーと同じ色にします。

shr_product_grid_fragment.xml で、ルート FrameLayout の最初の要素として、AppBarLayout の前に次のように追加します。

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="100dp"
   android:paddingBottom="100dp">

</LinearLayout>

styles.xml に以下を追加します。

styles.xml

<style name="Widget.Shrine.Backdrop" parent="">
   <item name="android:background">?attr/colorAccent</item>
</style>

これで完了です。Shrine の UI に美しい背景を追加しました。次に、メニューを追加します。

メニューを追加する

メニューは基本的にテキストボタンのリストです。ここに 1 つ追加します。

res -> layout ディレクトリに shr_backdrop.xml という新しいレイアウトを作成し、次の内容を追加します。

shr_backdrop.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_featured_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_apartment_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_accessories_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_shoes_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_tops_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_bottoms_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_dresses_label" />

   <View
       android:layout_width="56dp"
       android:layout_height="1dp"
       android:layout_margin="16dp"
       android:background="?android:attr/textColorPrimary" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_account_label" />

</merge>

このリストを、<include> タグを使用して shr_product_grid_fragment.xml で追加した LinearLayout に追加します。

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="88dp">

   <include layout="@layout/shr_backdrop" />
</LinearLayout>

ビルドして実行します。ホーム画面は次のようになります。

背景が完成しました。先ほど非表示にしたコンテンツを再表示しましょう。

この Codelab で Shrine に変更を加える前は、メインの商品コンテンツは一番奥のサーフェスにありました。背景を追加することで、コンテンツが背景の前に表示されるため、コンテンツがより強調されるようになりました。

新しいレイヤを追加する

商品グリッド レイヤを再度表示する必要があります。NestedScrollView から android:visibility="gone" 属性を削除します。

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

左上隅にノッチがあるスタイルをフロントレイヤに設定しましょう。マテリアル デザインでは、このようなカスタマイズが可能なコンポーネントをシェイプと呼びます。マテリアル サーフェスはさまざまな形状で表示できます。シェイプによってサーフェスに強調とスタイルを加え、ブランドを表現できます。マテリアル シェイプは、カーブまたは角度の付いた隅と縁、および任意の数の辺を持つことができます。また、対称または非対称にできます。

図形を追加する

グリッドの形状を変更します。カスタムのシェイプの背景を用意しましたが、このシェイプは Android Marshmallow 以降でのみ正しく表示されます。shr_product_grid_background_shape の背景は、Android Marshmallow 以降の NestedScrollView でのみ設定できます。まず、コードで参照できるように、次のように NestedScrollViewid を追加します。

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:id="@+id/product_grid"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

次に、ProductGridFragment.java でバックグラウンドをプログラムで設定します。onCreateView() の末尾(return ステートメントの直前)に、背景を設定する次のロジックを追加します。

ProductGridFragment.java

// Set cut corner background for API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    view.findViewById(R.id.product_grid).setBackgroundResource(R.drawable.shr_product_grid_background_shape);
}

最後に、productGridBackgroundColor カラーリソース(カスタムシェイプの背景でも使用)を次のように更新します。

colors.xml

<color name="productGridBackgroundColor">#FFFBFA</color>

ビルドして実行します。

これで、Shrine のプライマリ サーフェスにカスタム スタイルのシェイプが設定されました。サーフェスの高度により、白いフロントレイヤのすぐ後ろに何かがあることがユーザーにわかります。ユーザーがメニューを確認できるように、モーションを追加しましょう。

モーションは、アプリに命を吹き込む手段です。モーションは、大きくて目立つものでも、小さくて微妙なものでも、その中間のどんなものでもかまいません。使用するモーションが状況に適したものになるように留意する必要があります。反復される定期的なアクションに適用するモーションは、動作に時間がかかりすぎないように、小さくて微妙なものにする必要があります。一方、ユーザーが初めてアプリを開いたときのように、ユーザーの目を惹きつけることが適切な場合もあります。ある種のアニメーションは、アプリの使い方をユーザーに教えるのに役立ちます。

メニューボタンに開示モーションを追加する

モーションは、前面のシェイプがまっすぐ下に移動するものです。NavigationIconClickListener.java には、シートの翻訳アニメーションを実現するクリック リスナーがすでに用意されています。このクリック リスナーは、ProductGridFragment.javasetupToolbar() メソッド内で設定できます。

ProductGridFragment.java

toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));

setUpToolbar() メソッドは次のようになります。

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
}

ビルドして実行します。メニューボタンを押します。

ナビゲーション メニュー アイコンをもう一度押すと、メニューが非表示になります。

フロントレイヤの動きを調整

モーションは、ブランドを表現する優れた方法です。タイミング カーブを変更して、表示アニメーションがどのように見えるかを見てみましょう。

ProductGridFragment.javasetupToolbar() のコードを更新して、次のようにナビゲーション アイコンのクリック リスナーに Interpolator を渡します。

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
           getContext(),
           view.findViewById(R.id.product_grid),
           new AccelerateDecelerateInterpolator()));
}

これでは効果が異なります。

ブランドの図像も親しみやすいアイコンに拡張されています。開示アイコンをカスタマイズしてタイトルと結合し、ユニークなブランドをデザインしましょう。

メニューボタンのアイコンを変更する

メニューボタンを変更して、ひし形のデザインを含むアイコンを表示します。shr_product_grid_fragment.xml のツールバーを更新して、提供された新しいブランド アイコン(shr_branded_menu)を使用し、app:contentInsetStart 属性と android:padding 属性を設定して、ツールバーをデザイナーの仕様に合わせます。

shr_product_grid_fragment.xml

<androidx.appcompat.widget.Toolbar
   android:id="@+id/app_bar"
   style="@style/Widget.Shrine.Toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:paddingStart="12dp"
   android:paddingLeft="12dp"
   android:paddingEnd="12dp"
   android:paddingRight="12dp"
   app:contentInsetStart="0dp"
   app:navigationIcon="@drawable/shr_branded_menu"
   app:title="@string/shr_app_name" />

ProductGridFragment.javasetupToolbar() でクリック リスナーを再度更新し、メニューが開いているときと閉じているときのツールバーのドローアブルを取得します。

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
           getContext(),
           view.findViewById(R.id.product_grid),
           new AccelerateDecelerateInterpolator(),
           getContext().getResources().getDrawable(R.drawable.shr_branded_menu), // Menu open icon
           getContext().getResources().getDrawable(R.drawable.shr_close_menu))); // Menu close icon
}

ビルドして実行します。

良い傾向です。背景を表示できる場合は、ひし形メニュー アイコンが表示されます。メニューを非表示にできる場合は、代わりに閉じるアイコンが表示されます。

4 つの Codelab を実践することにより、マテリアル コンポーネントを使用して、ブランドの個性とスタイルを表現する独自の洗練されたユーザー エクスペリエンスを構築する方法を学びました。

次のステップ

この Codelab MDC-104 で一連の Codelab は完了です。Android ウィジェット カタログにアクセスすると、もっと多くの MDC-Android のコンポーネントを探究できます。

この Codelab のさらなる課題として、Shrine アプリケーションを変更して、バックドロップ メニューからカテゴリが選択されたときに表示される商品画像を変更してください。

作業用バックエンドのためにアプリを Firebase に接続する方法については、Firebase Android Codelab を参照してください。

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

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

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

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