MotionLayout
是一种布局类型,可帮助您管理应用中的运动和 widget 动画。
MotionLayout
是以下类的子类
ConstraintLayout
,并以其丰富的资源
布局功能作为 ConstraintLayout
库的一部分,MotionLayout
作为支持库提供。
MotionLayout
弥合了布局转换和复杂运动之间的差距
处理,在属性动画之间提供一系列功能
框架,
TransitionManager
和
CoordinatorLayout
。
除了描述布局之间的转换之外,MotionLayout
还可让您
为任何布局属性添加动画效果此外,它本身支持可搜索
过渡效果。也就是说,您可以立即显示转场效果中的任意时间点
根据某种条件(例如触控输入)进行调整。MotionLayout
还支持
支持完全自定义的转场效果,以满足您的需求。
MotionLayout
是完全声明性的,这意味着您可以描述
不管有多复杂
设计考虑事项
MotionLayout
旨在对符合以下条件的界面元素进行移动、调整大小和添加动画效果:
例如按钮和标题栏。请勿将应用中的动作
这种无用的特殊效果使用这些信息来帮助用户了解您的应用
工作内容如需详细了解如何设计具有动态效果的应用,请参阅
Material Design 部分了解
动作。
开始使用
请按照以下步骤开始在您的项目中使用 MotionLayout
。
-
添加
ConstraintLayout
依赖项:MotionLayout
,请将ConstraintLayout
2.0 依赖项build.gradle
文件。如果您使用的是 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 .../>
下面是
MotionLayout
文件的完整示例, 定义了图 1 中所示的布局: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>
-
在之前的
MotionLayout
中创建 MotionScene 例如,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>
每个动作端点。这些端点垂直居中 使用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>
本身包含两个属性:
motion:attributeName
是必需的,并且必须与具有 getter 和 setter 方法。getter 和 setter 必须与特定模式匹配。对于 例如,支持backgroundColor
,因为视图具有底层getBackgroundColor()
和setBackgroundColor()
方法。- 您必须提供的另一个属性基于值类型。可供选择的选项:
支持的类型:
<ph type="x-smartling-placeholder">
- </ph>
motion:customColorValue
适用于颜色motion:customIntegerValue
适用于整数motion:customFloatValue
适用于浮点值motion:customStringValue
适用于字符串motion:customDimension
适用于尺寸motion:customBoolean
适用于布尔值
指定自定义属性时,请同时定义起始位置和
<ConstraintSet>
元素的结尾。
更改背景颜色
基于上一个示例,假设您希望视图的颜色改变 作为运动的一部分,如图 2 所示。
<ph type="x-smartling-placeholder">向每个 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 部分)