使用MotionLayout 为Android创建动画

android studio 教程 | 2018-07-27 00:32

由于其卓越的多功能性,该ConstraintLayout 小部件已成为Android应用程序开发人员布局的“瑞士军刀”。但是,尽管可能,将复杂的动画添加到其内容中可能非常耗时。这就是谷歌MotionLayout 在I / O 2018中引入小部件的原因。

该MotionLayout 小部件现在是Android支持库的一部分,它扩展了 ConstraintLayout 小部件。它是一个独特的小部件,允许您使用XML以声明方式为其内容设置动画。此外,它还提供对其所有动画的细粒度控制。

在本教程中,我将向您展示如何将其添加到Android Studio项目中并使用它创建一些不同的动画。

先决条件

要学习本教程,您需要:

Android Studio 3.1.3或更高版本

运行Android API等级21或更高版本的设备或模拟器

对ConstraintLayout 小部件的基本了解

1.添加依赖项

为了能够MotionLayout 在Android Studio项目中使用窗口小部件,您必须将最新版本的Constraint Layout支持库作为 implementation 依赖项。此外,为避免版本冲突,请确保包含v7 appcompat支持库的最新稳定版本的依赖项。

因此,将以下代码添加到app 模块的build.gradle 文件中:

implementation 'com.android.support:appcompat-v7:27.0.2'

implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha1'

2.定义布局

该MotionLayout 插件可以做一切的ConstraintLayout 部件即可。因此,您可以使用前者自由替换后者的任何实例。但是,现在,我建议您创建一个新的布局XML文件,并将该MotionLayout 窗口小部件作为根元素添加到它。

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.motion.MotionLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@+id/motion_container">

<!-- More code here -->

</android.support.constraint.motion.MotionLayout>

在本教程中,我们将为ImageView 小部件设置动画。因此将其添加为布局的第一个子项。

<ImageView

android:id="@+id/actor"

app:srcCompat="@color/colorAccent"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

您可以自由地使用任何drawable作为ImageView 窗口小部件的源。在上面的代码中,我使用的是彩色绘图。

接下来,添加一个按钮,您可以按下该按钮以启动动画。以下代码显示如何将其放置在布局的中心:

android:id="@+id/button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Press Me"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintStart_toStartOf="parent"

app:layout_constraintTop_toTopOf="parent"

android:onClick="start"/>

此外,要监视动画的进度,请将SeekBar 小部件添加到布局并将其放置在按钮下方。就是这样:

<SeekBar

android:layout_width="100dp"

android:layout_height="wrap_content"

app:layout_constraintTop_toBottomOf="@+id/button"

app:layout_constraintEnd_toEndOf="parent"

app:layout_constraintStart_toStartOf="parent"

android:layout_marginTop="10dp"

android:id="@+id/seekbar"/>

最后,因为有一个与按钮关联的点击事件处理程序,请确保在您的活动中定义它。

fun start(v: View) {

// More code here

3.创建运动场景

您可能已经注意到我们ImageView 在定义布局时没有向窗口小部件添加任何约束。那是因为我们将把它们添加到运动场景中。运动场景是一个XML文件,其中包含有关要使用MotionLayout 窗口小部件创建的动画的详细信息。

要创建新的运动场景,请创建XML资源文件并向其添加 MotionScene 元素。<?xmlversion="1.0" encoding="utf-8"?>

<MotionScene

<!-- More code here -->

</MotionScene>

运动场景包含ConstraintSet 指定必须应用于动画中不同点的窗口小部件的约束的元素。运动场景文件通常包含两个约束集:一个用于动画的开头,另一个用于结束。

以下代码显示了如何创建两个约束集,以帮助 MotionLayout 窗口小部件将ImageView 窗口小部件从屏幕的右下角移动到左上角:<ConstraintSet android:id="@+id/starting_set">

<Constraint android:id="@+id/actor"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintRight_toRightOf="parent"

android:layout_width="60dp"

android:layout_height="60dp"

</ConstraintSet>

<ConstraintSet android:id="@+id/ending_set">

<Constraint android:id="@+id/actor"

app:layout_constraintTop_toTopOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

android:layout_width="60dp"

android:layout_height="60dp"

</ConstraintSet>

请注意,每个ConstraintSet 元素必须始终指定所需的位置和所需的大小。这很重要,因为它会覆盖任何以前设置的布局信息。

为了帮助MotionLayout 小部件理解必须应用约束集的顺序,您必须接下来创建一个Transition 元素。通过使用其直观命名 constraintSetStart 和constraintSetEnd 属性,您可以指定必须首先应用哪个集合以及最后应用哪个集合。该Transition 元素还允许您指定动画的持续时间。

<Transition

android:id="@+id/my_transition"

app:constraintSetStart="@+id/starting_set"

app:constraintSetEnd="@+id/ending_set"

app:duration="2000">

</Transition>

此时,运动场景完成。但是,MotionLayout 小部件仍然没有意识到它。因此,请返回布局XML文件,layoutDescription 向窗口小部件添加属性,并将其值设置为运动场景文件的名称。

如果您的运动场景文件的名称是my_scene.xml,则您的 窗口小部件现在应如下所示:MotionLayout<android.support.constraint.motion.MotionLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layoutDescription="@xml/my_scene"

android:id="@+id/motion_container">

</android.support.constraint.motion.MotionLayout>

4.启动动画

运行应用程序时,MotionLayout 窗口小部件将自动应用 元素constraintSetStart 属性中指定的约束集Transition。因此,要启动动画,您需要做的就是调用transitionToEnd() 窗口小部件的方法。以下代码必须添加到您在前面的步骤中创建的单击事件处理程序,它将向您显示如何:

motion_container.transitionToEnd()

此时,如果您运行应用程序并按下按钮,您应该能够看到 ImageView 小部件在屏幕上平滑移动。