Android 用マテリアル モーションで美しい遷移を作成する

1. はじめに

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

logo_components_color_2x_web_96dp.png

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

Android 用マテリアル モーション システムとは何ですか?

マテリアル デザイン ガイドラインに記載されているように、Android 用マテリアル モーション システムとは、MDC-Android ライブラリに含まれている移行パターンのセットです。ユーザーがアプリを理解し、操作しやすくなります。

主なマテリアル移行パターンには次の 4 つの種類があります。

  • コンテナ変換: コンテナを含む UI 要素間の移行。ある要素から別の要素にシームレスな変換を行うことで、2 つの異なる UI 要素の間に視覚的なつながりを作成します。
  • 共有軸: 空間関係またはナビゲーション関係がある UI 要素間の移行。x 軸、y 軸、z 軸で共有変換を使用して要素間の関係を強化します。
  • フェードスルー: 相互に強力な関係を持たない UI 要素間の移行。受信する要素の規模に応じて、フェードアウトとフェードインを連続的に使用します。
  • フェード: 画面の境界内で出入りする UI 要素に使用します。

MDC-Android ライブラリには、AndroidX Transition ライブラリandroidx.transition)と Android Transition Frameworkandroid.transition)の双方をベースに作成された、これらのパターン用の遷移クラスが用意されています。

AndroidX

  • com.google.android.material.transition パッケージで利用可能
  • API レベル 14 以上をサポート
  • フラグメントとビューはサポートされていますが、アクティビティとウィンドウはサポートされていません
  • バックポートされたバグの修正と、API レベル全体にわたる一貫した動作が含まれています

フレームワーク

  • com.google.android.material.transition.platform パッケージで利用可能
  • API レベル 21 以上をサポート
  • フラグメント、ビュー、アクティビティ、ウィンドウをサポート
  • バグの修正はバックポートされず、API レベルによって動作が異なる可能性があります

この Codelab では、AndroidX ライブラリをベースにしたマテリアル移行を使用します。つまり、主に Fragment と View に焦点を当てます。

作成するアプリの概要

この Codelab では、MDC-Android ライブラリの移行を使用してアプリのデザインをカスタマイズする方法を実習するために、Kotlin を使用して、Reply というサンプルの Android メールアプリにいくつかの移行を作成します。

Reply アプリのスターター コードが提供されます。そして、次のマテリアル移行をアプリに組み込みます。これは次のように、完成した Codelab の GIF に表示されます。

  • メール一覧からメール詳細ページへのコンテナ変換移行
  • FAB からメール作成ページへのコンテナ変換移行
  • 検索アイコンから検索ビューページへの z 軸共有移行
  • メールボックス ページ間のフェードスルー移行
  • メールアドレス チップからカード表示へのコンテナ変換移行

リクエストされた iframe のドメイン(youtu.be)がホワイトリストに登録されていません。

必要なもの

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

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

初心者 中級者 習熟者

2. 開発環境を設定する

Android Studio を起動する

Android Studio を開くと、「Welcome to Android Studio」というタイトルのウィンドウが表示されます。ただし、Android Studio を初めて起動している場合は、Android Studio 設定ウィザードの各手順を、デフォルト値を設定しながら進めていきます。このステップでは、必要なファイルのダウンロードとインストールに数分間かかる場合があります。バックグラウンドで実行させたまま、次のセクションに取り組んでもかまいません。

オプション 1: GitHub からスターター Codelab アプリのクローンを作成する

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

git clone https://github.com/material-components/material-components-android-motion-codelab.git
cd material-components-android-motion-codelab

オプション 2: スターター Codelab アプリの zip ファイルをダウンロードする

スターター アプリは material-components-android-motion-codelab-develop ディレクトリ内にあります。

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

  1. 設定ウィザードが終了し、[Welcome to Android Studio] ウィンドウが表示されたら、[Open an existing Android Studio project] をクリックします。

e3f200327a67a53.png

  1. サンプルコードをインストールしたディレクトリに移動し、サンプル ディレクトリを選択してプロジェクトを開きます。
  2. Android Studio がプロジェクトをビルドして同期するまで待ちます。進捗状況は、Android Studio ウィンドウ下部のアクティビティ インジケーターに表示されます。
  1. この時点では、Android SDK やビルドツール(以下に示すものなど)が不足しているため、Android Studio でビルドエラーが発生する場合があります。Android Studio の指示に従って、それをインストール / 更新して、プロジェクトを同期させます。引き続き問題が発生する場合は、SDK Manager でのツールの更新に関するガイドを参照してください。

6e026ae171f5b1eb.png

プロジェクトの依存関係を確認する

プロジェクトには、MDC-Android ライブラリへの依存関係が必要です。ダウンロードしたサンプルコードにはこの依存関係がすでにリストされているはずですが、設定を見て確認しましょう。

app モジュールの build.gradle ファイルに移動し、MDC-Android への依存関係が dependencies ブロックに含まれていることを確認します。

implementation 'com.google.android.material:material:1.2.0'

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

  1. デバイス選択の左側にあるビルド構成が app であることを確認します。
  2. 緑色の [Run / Play] ボタンを押して、アプリをビルドし実行します。

24218d0a6ae25803.png

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

完了しました。Reply のホームページのスターター コードがエミュレータで動作しているはずです。メール一覧を含む受信トレイが表示されます。

cc73eb0d0f779035.png

省略可: デバイスのアニメーションの速度を下げる

この Codelab には、簡単でありながら洗練された移行が含まれており、実装中の移行の詳細をより細かく確認する目的でデバイスのアニメーションの速度を下げる際に、便利に利用できます。これは、adb シェルコマンドまたはクイック設定タイルで実現できます。この方法でデバイスのアニメーションの速度を下げると、Reply アプリ外のデバイスのアニメーションにも影響します。

方法 1: ADB シェルコマンド

デバイスのアニメーションを 10 倍遅くするには、コマンドラインから次のコマンドを実行します。

adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10

デバイスのアニメーション速度を通常に戻すには、次のコマンドを実行します。

adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1

方法 2: クイック設定タイル

または、クイック設定タイルを設定するには、まずデバイスで開発者向け設定を有効にします(まだ有効にしていない場合)。

  1. デバイスの [設定] アプリを開きます。
  2. 一番下までスクロールして、[エミュレートされたデバイスについて] をクリックします。
  3. 一番下までスクロールし、[ビルド番号] をすばやくクリックして、デベロッパー設定を有効にします。

次に、デバイスの [設定] アプリで、クイック設定タイルを有効にするために次の操作を行います。

  1. 画面上部の検索アイコンまたは検索バーをクリックします。
  2. 検索フィールドに「タイル」と入力します。
  3. [開発者用のクイック設定タイル] 行をクリックします。
  4. [ウィンドウ アニメーション スケール] のスイッチをクリックします。

最後に、この Codelab 全体を通して、画面の上部からシステム通知シェードを引き下げ、c7e3f98200023f6a.png アイコンを使用して、アニメーションの速度を遅い速度と通常の速度の間で切り替えます。

3. サンプルアプリのコードを習得する

次に、コードを見てみましょう。Jetpack Navigation コンポーネント ライブラリを使用して、1 つのアクティビティ(MainActivity)内の複数のフラグメント間を移動するアプリを用意しました。

  • HomeFragment: メールの一覧が表示されます。
  • EmailFragment: 1 通のメールの全文が表示されます。
  • ComposeFragment: 新しいメールを作成できます。
  • SearchFragment: 検索ビューが表示されます。

まず、アプリのナビゲーション グラフの設定方法を理解するために、app -> src -> main -> res -> navigation ディレクトリで navigation_graph.xml を開きます。

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:id="@+id/navigation_graph"
   app:startDestination="@id/homeFragment">

   <fragment
       android:id="@+id/homeFragment"
       android:name="com.materialstudies.reply.ui.home.HomeFragment"
       android:label="HomeFragment">
       <argument...>
       <action
           android:id="@+id/action_homeFragment_to_emailFragment"
           app:destination="@id/emailFragment" />
   </fragment>
   <fragment
       android:id="@+id/emailFragment"
       android:name="com.materialstudies.reply.ui.email.EmailFragment"
       android:label="EmailFragment">
       <argument...>
   </fragment>
   <fragment
       android:id="@+id/composeFragment"
       android:name="com.materialstudies.reply.ui.compose.ComposeFragment"
       android:label="ComposeFragment">
       <argument...>
   </fragment>
   <fragment
       android:id="@+id/searchFragment"
       android:name="com.materialstudies.reply.ui.search.SearchFragment"
       android:label="SearchFragment" />
   <action
       android:id="@+id/action_global_homeFragment"
       app:destination="@+id/homeFragment"
       app:launchSingleTop="true"
       app:popUpTo="@+id/navigation_graph"
       app:popUpToInclusive="true"/>
   <action
       android:id="@+id/action_global_composeFragment"
       app:destination="@+id/composeFragment" />
   <action
       android:id="@+id/action_global_searchFragment"
       app:destination="@+id/searchFragment" />
</navigation>

上記のフラグメントがすべて存在し、デフォルトの起動フラグメントが app:startDestination="@id/homeFragment" を介して HomeFragment に設定されていることに注意してください。フラグメント デスティネーション グラフとアクションのこの XML 定義は、遷移をフックアップするときに発生する生成された Kotlin ナビゲーション コードに通知します。

activity_main.xml

次に、app -> src -> main -> res -> layout ディレクトリの activity_main.xml レイアウトを見てみましょう。上記で作成したナビゲーション グラフで構成された NavHostFragment が表示されます。

<fragment
   android:id="@+id/nav_host_fragment"
   android:name="androidx.navigation.fragment.NavHostFragment"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:defaultNavHost="true"
   app:navGraph="@navigation/navigation_graph"/>

この NavHostFragment は画面全体を埋め、アプリ内の全画面フラグメントのナビゲーションの変更をすべて処理します。BottomAppBar とそのアンカー FloatingActionButtonactivity_main.xml 内)は、NavHostFragment によって表示される現在のフラグメントの上にレイアウトされるため、提供されたサンプルアプリコードによってフラグメントの宛先に応じて表示または非表示になります。

また、activity_main.xmlBottomNavDrawerFragment は、さまざまなメールボックス間を移動するためのメニューを含むボトムドロワーです。これは、BottomAppBar 返信ロゴボタンを介して条件付きで表示されます。

MainActivity.kt

最後に、使用されているナビゲーション アクションの例を確認するには、app -> src -> main -> java -> com.materialstudies.reply.ui ディレクトリにある MainActivity.kt を開きます。navigateToSearch() 関数を見つけます。この関数は次のようになります。

private fun navigateToSearch() {
   val directions = SearchFragmentDirections.actionGlobalSearchFragment()
   findNavController(R.id.nav_host_fragment).navigate(directions)
}

これは、カスタム移行なしで検索ビューページに移動する方法を示しています。この Codelab では、アプリ中のさまざまなナビゲーション アクションと連動するマテリアル移行を設定するための Reply の MainActivity と 4 つのメイン フラグメントについて、詳しく説明します。

スターター コードに慣れてきたところで、最初の移行を実装してみましょう。

4. メール一覧からメール詳細ページへのコンテナ変換移行を追加する

まず、メールをクリックしたときの移行を追加します。このナビゲーション変更には、コンテナを含む UI 要素間の移行を考慮して設計されたコンテナ変換パターンが適しています。このパターンでは、2 つの UI 要素間に視覚的なつながりが作成されます。

コードを追加する前に、Reply アプリを実行してメールをクリックしてみましょう。単純なジャンプカットが実行されます。つまり、移行なしで画面が切り替わります。

f0e8a92eb2216bce.gif

まず、次のスニペットに示すように、email_item_layout.xmlMaterialCardViewtransitionName 属性を追加します。

email_item_layout.xml

android:transitionName="@{@string/email_card_transition_name(email.id)}"

トランジション名には、パラメータを含む文字列リソースが渡されます。メールごとに ID を使用して、EmailFragment の各 transitionName が一意であることを確認する必要があります。

メールリスト アイテムのトランジション名を設定したので、メールの詳細レイアウトでも同じことを行います。fragment_email.xml で、MaterialCardViewtransitionName を次の文字列リソースに設定します。

fragment_email.xml

android:transitionName="@string/email_card_detail_transition_name"

HomeFragment.kt で、onEmailClicked のコードを次のスニペットに置き換えて、開始ビュー(メールリスト アイテム)と終了ビュー(メールの詳細画面)のマッピングを作成します。

HomeFragment.kt

val emailCardDetailTransitionName = getString(R.string.email_card_detail_transition_name)
val extras = FragmentNavigatorExtras(cardView to emailCardDetailTransitionName)
val directions = HomeFragmentDirections.actionHomeFragmentToEmailFragment(email.id)
findNavController().navigate(directions, extras)

配管が構成されたので、コンテナ変換を作成できます。EmailFragment onCreate メソッドで、次のスニペットを追加して、sharedElementEnterTransitionMaterialContainerTransform の新しいインスタンスに設定します(com.google.android.material.transition.platform バージョンではなく com.google.android.material.transition バージョンをインポートします)。

EmailFragment.kt

sharedElementEnterTransition = MaterialContainerTransform().apply {
   drawingViewId = R.id.nav_host_fragment
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   scrimColor = Color.TRANSPARENT
   setAllContainerColors(requireContext().themeColor(R.attr.colorSurface))
}

アプリを再実行してみてください。

ed62cedec31da268.gif

視覚的な効果が向上しています。メール一覧でメールをクリックすると、コンテナ変換によってリスト項目が展開され、全画面の詳細ページが表示されます。ただし、[戻る] を押してもメールがリストに戻らないことに注意してください。また、切り替えの開始時にメールリストがすぐに消え、グレーのウィンドウの背景が表示されます。つまり、まだ完了していません。

戻り遷移を修正するには、HomeFragment.ktonViewCreated メソッドに次の 2 行を追加します。

HomeFragment.kt

postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }

アプリを再実行してみてください。メールを開いた後に [戻る] を押すと、メールがたたまれてリストに戻ります。良い傾向です。アニメーションの改善を続けましょう。

メールリストが消える問題は、Navigation コンポーネントを使用して新しいフラグメントに移動する際に、現在のフラグメントがすぐに削除され、新しい受信フラグメントに置き換えられることが原因です。メールリストが置き換えられた後も表示されるようにするには、HomeFragment に終了トランジションを追加します。

次のスニペットを HomeFragment onEmailClicked メソッドに追加すると、終了時にメール一覧がわずかにスケールアウトし、再入力時にスケールインします。

HomeFragment.kt

exitTransition = MaterialElevationScale(false).apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}

次に、MaterialElevationScale トランジションが階層内の個々のビューではなく、ホーム画面全体に適用されるように、fragment_home.xmlRecyclerView をトランジション グループとしてマークします。

fragment_home.xml

android:transitionGroup="true"

この段階で、コンテナ変換は完全に機能しているはずです。メールをクリックすると、リスト項目が展開されて詳細画面になり、メール一覧が後退します。[戻る] を押すと、メール詳細画面がたたまれてリスト項目に戻り、メール一覧が拡大します。

9df2b39d5a150418.gif

5. FAB からメール作成ページへのコンテナ変換移行を追加する

コンテナ変換を続行し、フローティング アクション ボタンから ComposeFragment への移行を追加して、ユーザーによって作成される新しいメールに FAB を展開します。まずアプリを再実行して FAB をクリックし、メール作成画面を開いても移行が行われないことを確認します。

d242c9708abd382c.gif

同じトランジション クラスを使用しますが、FAB は MainActivity にあり、ComposeFragmentMainActivity Navigation ホスト コンテナ内に配置されているため、このインスタンスの構成方法は異なります。

ComposeFragment.kt で、次のスニペットを onViewCreated メソッドに追加し、必ず Slideandroidx.transition バージョンをインポートします。

ComposeFragment.kt

enterTransition = MaterialContainerTransform().apply {
   startView = requireActivity().findViewById(R.id.fab)
   endView = emailCardView
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   scrimColor = Color.TRANSPARENT
   containerColor = requireContext().themeColor(R.attr.colorSurface)
   startContainerColor = requireContext().themeColor(R.attr.colorSecondary)
   endContainerColor = requireContext().themeColor(R.attr.colorSurface)
}
returnTransition = Slide().apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_medium).toLong()
   addTarget(R.id.email_card_view)
}

以前のコンテナ変換の設定に使用したパラメータに加えて、startViewendView がここで手動で設定されています。transitionName 属性を使用して、どのビューを変換するかを Android Transition システムに通知する代わりに、必要に応じて手動で指定できます。

アプリを再実行します。FAB が作成画面に変換されるはずです(このステップの最後にある GIF を参照)。

前の手順と同様に、HomeFragment が削除されて ComposeFragment に置き換えられた後に消えないように、HomeFragment にトランジションを追加する必要があります。

次のスニペットを MainActivitynavigateToCompose メソッドの NavController navigate の呼び出しの前にコピーします。

MainActivity.kt

currentNavigationFragment?.apply {
   exitTransition = MaterialElevationScale(false).apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
   reenterTransition = MaterialElevationScale(true).apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
}

これで完了です。FAB から作成画面への移行は次のようになるはずです。

81b68391ac4b0a9.gif

6. 検索アイコンから検索ビューページへの z 軸共有移行を追加する

このステップでは、検索アイコンから全画面検索ビューへの移行を追加します。このナビゲーション変更には永続的なコンテナが関わってないため、z 軸共有移行を使用して、2 つの画面間の空間関係を強化し、アプリの階層内での 1 段階上昇を示すことができます。

コードを追加する前に、アプリを実行し、画面右下隅の検索アイコンをタップしてみましょう。移行なしで検索ビュー画面が表示されるはずです。

499e1a677b4216bb.gif

まず、MainActivitynavigateToSearch メソッドを見つけ、NavController navigate メソッド呼び出しの前に次のコード スニペットを追加して、現在のフラグメントの終了と再開の MaterialSharedAxis Z 軸遷移を設定します。

MainActivity.kt

currentNavigationFragment?.apply {
   exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
   reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
}

次に、SearchFragmentonCreate メソッドに次のコード スニペットを追加します。このコードは、エントリと戻りの MaterialSharedAxis トランジションを構成します。

SearchFragment.kt

enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}

最後に、階層内の個々のビューではなく、検索画面全体に MaterialSharedAxis のトランジションが適用されるように、fragment_search.xmlLinearLayout をトランジション グループとしてマークします。

fragment_search.xml

android:transitionGroup="true"

これで、アプリをもう一度実行し、検索アイコンをタップしてみてください。ホーム画面と検索ビュー画面は、Z 軸に沿って深さを同時にフェードまたはスケーリングさせ、2 つの画面の間にシームレスな効果をもたらします。

e5c0b0a130e807db.gif

7. メールボックス ページ間のフェードスルー移行を追加する

このステップでは、異なるメールボックス間の移行を追加します。空間的または階層的な関係は強調したくないため、フェードスルーを使用してメール一覧間の単純な「スワップ」を行います。

コードを追加する前に、アプリを実行し、ボトム アプリバーの Reply ロゴをタップして、メールボックスの切り替えを行ってみましょう。移行なしでメール一覧が切り替わるはずです。

2c874c0a4588e8fb.gif

まず、MainActivitynavigateToHome メソッドを見つけ、NavController navigate メソッド呼び出しの前に次のコード スニペットを追加して、現在のフラグメントの終了 MaterialFadeThrough 遷移を設定します。

MainActivity.kt

currentNavigationFragment?.apply {
   exitTransition = MaterialFadeThrough().apply {
       duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
   }
}

次に、HomeFragment を開きます。onCreate で、フラグメントの enterTransitionMaterialFadeThrough の新しいインスタンスに設定します。

HomeFragment.kt

enterTransition = MaterialFadeThrough().apply {
   duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}

アプリを再実行します。ボトム ナビゲーション ドロワーを開いてメールボックスを変更すると、現在のメール一覧がフェードしてスケールアウトする一方で、新しい一覧がフェードしてスケールインします。すばらしいですね!

f61dfd58ea7bd3fd.gif

8. メールアドレス チップからカード表示へのコンテナ変換移行を追加する

このステップでは、チップをポップアップ カードに変換するトランジションを追加します。ここでは、ポップアップで行われた操作がポップアップの発生元であるチップに影響することをユーザーに知らせるために、コンテナ変換が使用されています。

コードを追加する前に、Reply アプリを実行し、メールをクリックして [返信] FAB をクリックしてから、受信者の連絡先チップをクリックしてみましょう。チップがすぐに消え、その連絡先のメールアドレスが記載されたカードがアニメーションなしで表示されます。

6200c682da2382d5.gif

このステップでは、ComposeFragment で作業します。ComposeFragment レイアウトには、すでに宛先チップ(デフォルトで表示)と宛先カード(デフォルトで非表示)が追加されています。受信者チップとこのカードは、コンテナ変換を作成する 2 つのビューです。

まず、ComposeFragment を開き、expandChip メソッドを見つけます。このメソッドは、指定された chip がクリックされると呼び出されます。recipientCardViewchip の表示状態を入れ替える行の上に次のコード スニペットを追加します。これにより、beginDelayedTransition を介して登録されたコンテナ変換がトリガーされます。

ComposeFragment.kt

val transform = MaterialContainerTransform().apply {
   startView = chip
   endView = binding.recipientCardView
   scrimColor = Color.TRANSPARENT
   endElevation = requireContext().resources.getDimension(
       R.dimen.email_recipient_card_popup_elevation_compat
   )
   addTarget(binding.recipientCardView)
}

TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)

アプリを実行すると、チップが受信者のメールアドレスのカードに変換されます。次に、カードをチップに折りたたむように戻り遷移を構成します。

ComposeFragmentcollapseChip メソッドに、カードをチップに閉じるための次のコード スニペットを追加します。

ComposeFragment.kt

val transform = MaterialContainerTransform().apply {
   startView = binding.recipientCardView
   endView = chip
   scrimColor = Color.TRANSPARENT
   startElevation = requireContext().resources.getDimension(
       R.dimen.email_recipient_card_popup_elevation_compat
   )
   addTarget(chip)
}

TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)

アプリを再実行します。チップをクリックするとチップがカードに展開され、カードをクリックするとカードがチップに折りたたまれます。すばらしいですね!

e823b28e2890e05d.gif

9. 完了

MDC-Android ライブラリは、100 行未満の Kotlin コードといくつかの基本的な XML マークアップを使用して、マテリアル デザインのガイドラインに準拠した美しい移行を既存のアプリに作成する作業を支援します。また、すべての Android デバイスで一貫した外観と動作を実現します。

454a47ba96017a25.gif

次の手順

マテリアル モーション システムの詳細については、仕様デベロッパー向けドキュメント全文を確認し、いくつかのマテリアル移行をアプリに追加してみてください。

マテリアル モーションをお試しいただきありがとうございます。この Codelab がお役に立ちましたら幸いです。

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

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

今後もマテリアル モーション システムを使いたい

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