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-alpha13" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13") }
-
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>
では、モーションを表現するさまざまな制約を定義します。この例では、モーションのエンドポイントごとに 1 つの<ConstraintSet>
が定義されています。これらのエンドポイントは、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)