使用MotionLayout for Android创建动画

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

现在是Android支持库一部分的MotionLayout小部件扩展了ConstraintLayout小部件。 它是一个独特的小部件,允许您仅使用XML声明性地对其内容进行动画处理。 此外,它提供了对其所有动画的细粒度控制。

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

先决条件

要遵循本教程,您需要:

  • Android Studio 3.1.3或更高版本
  • 运行Android API级别21或更高版本的设备或模拟器
  • ConstraintLayout小部件的基本了解

1.添加依赖项

为了能够在Android Studio项目中使用MotionLayout小部件,您必须具有最新版本的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小部件作为根元素添加到该文件中。




    

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

您可以随意使用任何可绘制对象作为ImageView小部件的源。 在上面的代码中,我使用了可绘制的颜色。

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

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

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

fun start(v: View) {
    // More code here        
}

3.创建运动场景

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

要创建一个新的运动场景,请创建一个XML资源文件并向其中添加一个MotionScene元素。




    
    

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

以下代码显示了如何创建两个约束集,这些约束集将帮助MotionLayout小部件将ImageView小部件从屏幕的右下角移至左上角:


    



    

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

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


    

至此,运动场景完成。 但是, MotionLayout小部件仍然不知道它。 因此,返回到布局XML文件,向小部件添加layoutDescription属性,并将其值设置为运动场景文件的名称。

如果运动场景文件的名称为my_scene.xml ,则MotionLayout小部件现在应如下所示:



    ...

4.开始动画

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

motion_container.transitionToEnd()

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

5.处理动画事件

通过将TransitionListener对象附加到MotionLayout小部件,您可以密切监视动画的进度。

motion_container.setTransitionListener(
    object: MotionLayout.TransitionListener {
        // More code here        
    }
)

TransitionListener接口具有两种抽象方法,Android Studio会自动为它们生成存根。

当从一个约束集到另一个约束集的转换完成时,将调用onTransitionCompleted()方法。 现在,让我们使用它通过调用其中的transitionToStart()方法来重置ImageView小部件的约束。

override fun onTransitionCompleted(motionLayout: MotionLayout?,
                                   currentId: Int) {
    if(currentId == R.id.ending_set) {
        // Return to original constraint set
        motion_container.transitionToStart()
    }
}

每次动画进度更改时,都会调用onTransitionChange()方法。 因此,进度是一个介于零和一之间的浮点数。 以下代码显示了如何根据动画的进度更新SeekBar

override fun onTransitionChange(motionLayout: MotionLayout?,
                                startId: Int,
                                endId: Int,
                                progress: Float) {
    seekbar.progress = ceil(progress * 100).toInt()
}

继续并再次运行该应用程序,现在可以看到两个动画。

6.创建关键帧

在我们的动画中, ImageView小部件在看起来像直线的路径中移动。 这是因为MotionLayout小部件仅提供了两个要使用的点:起点(位于屏幕的右下角)和终点(位于屏幕的左上角)。 如果要更改路径的形状,则必须提供一些中间点,该中间点位于起点和终点之间。 为此,您必须创建新的关键帧。

但是,在开始创建关键帧之前,必须将KeyFrameSet元素添加到运动场景的Transition元素。 在新元素内,您可以自由创建任意数量的关键帧。


    

MotionLayout小部件支持许多不同类型的关键帧。 在本教程中,我们将仅使用两种类型: KeyPosition框架和KeyCycle框架。

KeyPosition框架可帮助您更改路径的形状。 创建它们时,请确保提供目标窗口小部件的ID,时间轴上的位置(可以是0到100之间的任何数字)以及所需的X或Y坐标(以百分比表示)。 坐标可以相对于实际的X轴或Y轴,也可以相对于路径本身。

以下代码显示了如何创建两个关键帧,这些关键帧迫使ImageView小部件遵循避免与按钮和搜寻栏发生冲突的路径:


    

如果现在运行该应用程序,则应该看到一个动画,如下所示:

当然,您可以自由添加更多关键帧。 例如,通过在时间轴的末尾添加以下关键帧,可以使ImageView小部件遵循更波浪的路径:

通过同时使用KeyCycle框架和KeyPosition框架,可以向动画添加振荡。 创建它时,必须再次提供目标窗口小部件的ID,时间轴上的位置以及必须来回振荡的属性的期望值。 此外,必须通过提供详细信息(例如要使用的波形和波形周期)来配置振荡器。

下面的代码创建一个KeyCycle框架,该框架使用正弦波振荡器将ImageView小部件周期性地旋转50度:

再次运行该应用程序时,您应该看到一个动画,如下所示:

7.使动画小部件具有交互性

这期间,您一直在按一个按钮来启动动画。 但是,并非总是需要这样的按钮,因为MotionLayout小部件允许您将触摸事件处理程序直接附加到要设置动画的小部件。 当前,它支持单击和滑动事件。

例如,您可以在运动场景的Transition元素内添加以下针对ImageView小部件的OnClick元素,以使按钮多余:

同样,您可以使用OnSwipe元素来允许用户在屏幕上手动拖动ImageView小部件。 创建元素时,必须确保提供正确的拖动方向以及应用作拖动手柄的小部件侧面。

如果再次运行该应用程序,现在应该可以拖动ImageView小部件。

结论

现在,您知道如何使用MotionLayout小部件快速向您的Android应用添加复杂的交互式动画。 您可以确定,只要避免嵌套视图,动画就可以在大多数设备上无滞后或抖动的情况下运行。

值得注意的是,即将发布的Android Studio版本将包含一个可视化的Motion编辑器,这可能会进一步提高小部件的可用性。

要了解更多信息,请参阅官方文档 。

翻译自: https://code.tutsplus.com/tutorials/creating-animations-with-motionlayout-for-android--cms-31497

你可能感兴趣的:(使用MotionLayout for Android创建动画)