MotionLayout
は、アプリ内のモーションとウィジェットのアニメーションを管理できるレイアウト タイプです。MotionLayout
は ConstraintLayout
のサブクラスであり、その豊富なレイアウト機能を基礎としています。ConstraintLayout
ライブラリの一部として、MotionLayout
はサポート ライブラリとして使用できます。
MotionLayout
はレイアウトの遷移と複雑なモーションの処理の橋渡しをしており、プロパティ アニメーション フレームワーク、TransitionManager
、CoordinatorLayout
の機能を合わせて提供します。
MotionLayout
を使用すると、レイアウト間の遷移を記述するだけでなく、レイアウト プロパティをアニメーション化できます。さらに、シーク可能な遷移ももともとサポートしています。それにより、タップ入力などのなんらかの条件に基づいて、遷移内の任意のポイントをすぐに表示することもできます。MotionLayout
はキーフレームにも対応しており、必要に応じて完全にカスタマイズした遷移も可能です。
MotionLayout
は完全に宣言型なので、どのような遷移も、どれほど複雑であっても、XML で記述することができます。
設計に関する注意事項
MotionLayout
は、ボタンやタイトルバーなど、ユーザーが操作する UI 要素の移動、サイズ変更、アニメーション化を行うためのものです。アプリ内のモーションは、おまけの特殊効果として使用しないでください。アプリが何をしているかをユーザーに理解してもらうために使用します。モーションを含むアプリの設計について詳しくは、マテリアル デザインのモーションについてのセクションをご覧ください。
始める
プロジェクトで MotionLayout
を使用する手順は次のとおりです。
-
ConstraintLayout
依存関係を追加する: プロジェクトでMotionLayout
を使用するには、アプリのbuild.gradle
ファイルにConstraintLayout
2.0 依存関係を追加します。AndroidX を使用している場合は、次の依存関係を追加します。Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
-
MotionLayout
ファイルを作成する:MotionLayout
はConstraintLayout
のサブクラスであるため、下記の例に示すように、レイアウト リソース ファイル内のクラス名を置き換えることで、既存のConstraintLayout
をMotionLayout
に変換できます。AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
サポート ライブラリ
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
図 1 に示すレイアウトを定義する
MotionLayout
ファイルの完全な例を次に示します。AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
サポート ライブラリ
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
MotionScene を作成する: 上記の
MotionLayout
の例では、app:layoutDescription
属性は モーション シーンを参照しています。モーション シーンは XML リソース ファイルです。モーション シーンの<MotionScene>
ルート要素には、対応するレイアウトのモーションの記述がすべて含まれます。レイアウト情報とモーションの記述を分離しておくため、MotionLayout
はそれぞれ別のモーション シーンを参照します。モーション シーン内の定義は、MotionLayout
内の同様の定義よりも優先されます。図 1 の基本的な水平方向の動きを記述するモーション シーン ファイルの例を次に示します。
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
次の点にご注意ください。
-
<Transition>
にはモーションの基本定義が含まれます。-
motion:constraintSetStart
とmotion:constraintSetEnd
は、モーションの端点を示します。これらのエンドポイントは、モーション シーンの後方の<ConstraintSet>
要素で定義されます。 -
motion:duration
は、モーションが完了するまでにかかるミリ秒数を示します。
-
-
<OnSwipe>
: モーションのタップ操作を作成できます。-
motion:touchAnchorId
は、ユーザーがスワイプとドラッグできるビューを示します。 -
motion:touchAnchorSide
は、ビューが右側からドラッグされていることを示します。 -
motion:dragDirection
は、ドラッグの進行方向を示します。たとえばmotion:dragDirection="dragRight"
の場合、ビューを右にドラッグすると進行状況が増えます。
-
-
<ConstraintSet>
には、モーションを記述するさまざまな制約を定義します。この例では、モーションの各端点に対して<ConstraintSet>
を 1 つずつ定義します。これらのエンドポイントは、app:layout_constraintTop_toTopOf="parent"
とapp:layout_constraintBottom_toBottomOf="parent"
を使用して垂直方向の中央に配置されます。水平方向の端点は、画面の左端と右端にあります。
モーション シーンでサポートされるさまざまな要素について詳しくは、MotionLayout の例をご覧ください。
-
補間される属性
モーション シーン ファイル内の ConstraintSet
要素には、遷移中に補間される追加属性を含めることができます。位置と境界に加え、以下の属性が MotionLayout
で補間されます。
alpha
visibility
elevation
rotation
、rotationX
、rotationY
translationX
、translationY
、translationZ
scaleX
、scaleY
カスタム属性
<Constraint>
内には、<CustomAttribute>
要素を使って、位置や View
の属性とは直接関連しない属性の遷移を指定できます。
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
<CustomAttribute>
には、固有の属性が 2 つあります。
motion:attributeName
は必須で、ゲッター メソッドとセッター メソッドを持つオブジェクトと一致する必要があります。ゲッターとセッターは特定のパターンに一致する必要があります。たとえば、ビューには基礎になるgetBackgroundColor()
メソッドとsetBackgroundColor()
メソッドがあるので、backgroundColor
がサポートされています。- 他の属性は値のタイプに基づいて指定する必要があります。サポートされている次のタイプから選択します。
motion:customColorValue
: 色motion:customIntegerValue
: 整数motion:customFloatValue
: 浮動小数点motion:customStringValue
: 文字列motion:customDimension
: サイズmotion:customBoolean
: ブール値
カスタム属性を指定する場合は、開始と終了の両方の <ConstraintSet>
要素でエンドポイント値を定義します。
背景色を変更する
前述の例を基に、図 2 に示すように、ビューの色をモーションの一部として変更するとします。
次のコード スニペットに示すように、各 ConstraintSet
要素に <CustomAttribute>
要素を追加します。
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet>
その他の MotionLayout 属性
上記の例の属性に加えて、MotionLayout
には必要に応じて他の属性を指定できます。
app:applyMotionScene="boolean"
は、モーション シーンを適用するかどうかを示します。この属性のデフォルト値はtrue
です。app:showPaths="boolean"
は、モーションの実行中にモーションパスを表示するかどうかを指定します。この属性のデフォルト値はfalse
です。app:progress="float"
を使って、遷移の進行状況を明示的に指定できます。0
(遷移の開始)から1
(遷移の終了)までの任意の浮動小数点値を使用できます。app:currentState="reference"
を使って特定のConstraintSet
を指定できます。app:motionDebug
を使ってモーションに関するその他のデバッグ情報を表示できます。指定可能な値は"SHOW_PROGRESS"
、"SHOW_PATH"
、"SHOW_ALL"
です。
参考情報
MotionLayout
の詳細については、次のリソースをご覧ください。
- Kotlin 03.2 での高度な Android: MotionLayout を使用したアニメーション
- MotionLayout の例
- GitHub の MotionLayout/ConstraintLayout のサンプル
- MotionLayout の概要(パート I)
- MotionLayout の概要(パート II)
- MotionLayout の概要(パート III)
- MotionLayout の概要(パート IV)