MotionLayout は、アプリ内のモーションとウィジェットのアニメーションを管理できるレイアウト タイプです。MotionLayout は ConstraintLayout のサブクラスであり、その豊富なレイアウト機能を基礎としています。ConstraintLayout ライブラリの一部として、MotionLayout はサポート ライブラリとして使用できます。
MotionLayout はレイアウトの遷移と複雑なモーションの処理の橋渡しをしており、プロパティ アニメーション フレームワーク、TransitionManager、CoordinatorLayout の機能を合わせて提供します。
MotionLayout は、レイアウト間の遷移を記述するだけでなく、レイアウト プロパティをアニメーション化することもできます。さらに、シーク可能な遷移ももともとサポートしています。それにより、タップ入力などのなんらかの条件に基づいて、遷移内の任意のポイントをすぐに表示することもできます。MotionLayout はキーフレームにも対応しており、必要に応じて完全にカスタマイズした遷移も可能です。
MotionLayout は完全に宣言型なので、どのような遷移も、どれほど複雑であっても、XML で記述することができます。
設計に関する注意事項
MotionLayout は、ボタンやタイトルバーなど、ユーザーが操作する UI 要素を移動、サイズ変更、アニメーション化するためのものです。アプリ内のモーションは、おまけの特殊効果として使用しないでください。アプリが何をしているかをユーザーに理解してもらうために使用します。モーションを含むアプリの設計について詳しくは、マテリアル デザインのモーションについてのセクションをご覧ください。
始める
プロジェクトで MotionLayout を使用する手順は次のとおりです。
- 
    
ConstraintLayout依存関係を追加する: プロジェクトでMotionLayoutを使用するには、アプリのbuild.gradleファイルにConstraintLayout2.0 依存関係を追加します。AndroidX を使用している場合は、次の依存関係を追加します。Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.1" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.1") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1") }
 - 
    
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 で補間されます。
alphavisibilityelevationrotation、rotationX、rotationYtranslationX、translationY、translationZscaleX、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)