目录
Android之MotionLayout(一),MotionLayout的基本使用
Android之MotionLayout(二),MotionScene的标签属性说明
Android之MotionLayout(三),用 MotionLayout 来做过渡动画,如何使用ConstraintSet
Android之MotionLayout(四),用 MotionLayout实现向上拉的折叠效果
Android之MotionLayout(五),如何使用 MotionLayout的自定义属性
Android之MotionLayout(六),如果使用Keyframes实现实现YouTube切换效果
前言
- 学习MotionLayout之前你必须了解约束布局
ConstraintLayout
-
MotionLayout
是ConstraintLayout
的子类,在其丰富的布局功能基础之上构建而成
由于 MotionLayout 是基于 ConstraintLayout ,所以其中涉及到了部分关于 ConstraintLayout 的基本知识,本文按下不表,对 ConstraintLayout 不熟悉的同学,可以查看鸿洋的这篇博客。
MotionLayout简介
MotionLayout 是一个 Google 官方出品用于制作 Android 中的过渡动画的框架。用来它就能轻松的做出一些较为复杂的动画效果
我们看一下效果图:
开始使用MotionLayout
添加支持库:
如果您使用了 AndroidX
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
}
如果您没有使用 AndroidX
dependencies {
implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1'
}
MotionLayout 最低支持到 Android 4.3(API 18),还有就是 MotionLayout 是 ConstraintLayout 2.0 添加的,因此必须确保支持库的版本不低于 2.0。
由于 MotionLayout 类继承自 ConstraintLayout 类,因此可以在布局中使用 MotionLayout 替换掉 ConstraintLayout
MotionLayout 与 ConstraintLayout 不同的是:
MotionLayout 需要链接到一个MotionScene
文件。使用 MotionLayout 的 app:layoutDescription
属性将 MotionLayout 链接到一个MotionScene
文件。
开始使用MotionLayout
在之前的 MotionLayout 示例中,app:layoutDescription 属性引用一个 MotionScene。MotionScene 是一个 XML 资源文件,其中包含相应布局的所有运动描述。为了将布局信息与运动描述分开,每个 MotionLayout 都引用一个单独的 MotionScene。请注意,MotionScene 中的定义优先于 MotionLayout 中的任何类似定义。
MotionScene 文件描述了两个场景间的过渡动画,存放在 res/xml 目录下。
要使用 MotionLayout 创建过渡动画,你需要创建两个 layout 布局文件来描述两个不同场景的属性。当从一个场景切换到另一个场景时,MotionLayout 框架会自动检测这两个场景中具有相同 id 的 View 的属性差别,然后针对这些差别属性应用过渡动画(类似于 TransitionManger)
MotionLayout 框架支持的标准属性:
android:visibility
android:alpha
android:elevation
android:rotation
android:rotationX
android:rotationY
android:scaleX
android:scaleY
android:translationX
android:translationY
android:translationZ
MationLayout 除了支持上面列出的标准属性外,还支持全部的 ConstraintLayout 属性。
我们来分三步完成线面这个例子
第 1 步:创建场景 1 的布局文件:
文件名 activity_scene1
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:showPaths="true"
app:layoutDescription="@xml/activity_motion_scene">
<ImageView
android:id="@+id/image"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/bg_circular"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
场景1布局效果
第 2 步:创建场景 2 的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:showPaths="true"
app:layoutDescription="@xml/activity_motion_scene">
<ImageView
android:id="@+id/image"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/bg_circular"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
场景2布局效果
说明:场景 1 与场景 2 中都有一个 id 值为 image 的 ImageView,它们的差别是:场景 1 中的 image 是水平垂直居中放置的,而场景 2 中的 image 是水平居中,垂直对齐到父布局顶部的。因此当从场景 1 切换到场景 2 时,MotionLayout 将针对 image 的位置差别自动应用位移过渡动画。
第 3 步:创建 MotionScene 文件:
文件名:activity_motion_scene.xml,存放在 res/xml 目录下
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetStart="@layout/activity_main_scene1"
app:constraintSetEnd="@layout/activity_main_scene2"
app:duration="1000">
<OnClick
app:clickAction="toggle"
app:targetId="@id/image" />
</Transition>
</MotionScene>
编写完 MotionLayout 文件后就可以直接运行程序了。点击 image 即可进行场景切换。当进行场景切换时,MotionLayout 会自动计算出两个场景之间的差别,然后应用相应的过渡动画
如果你想向文章开始示意图里显示路径的话 在布局文件的根目录增加
app:showPaths="true"