MotionLayout 简单使用.

889 阅读2分钟

动画作为Android开发里重要部分,在以前,Android 开发者想要实现产品提出动画的需求,会使用属性动画或系统提供的动画库完成,然后编译,发现有点不对劲,再微调,再部署,这样的反反复复经历几轮,无论是开发成本还是学习成本比较大的。最近, 我发现 MotionLayout,可以让整个流程的效率得到提升,但是当我安利给小伙伴时, 会听到他们说,有点难,我猜测,难的原因可能是国内鲜有MotionLayout的教程,今天,我把自己的理解过程分享在这里。

如何实现动画

实现动画的前提,要知道什么是动画

物体从A形态平滑过渡至B形态的过程

所以为了实现动画,我们要从两个方面入手:

  • 定义A、B形态
  • 找到实现平滑过渡的方式

所以,我们在使用 MotionLayout 过程中,其实就是去寻找以上两个概念如何在 MotionLayout 中落地.

先看效果图:

那 MotionLayout 如何实现上面的效果呢....

MotionLayout

官网是这么介绍的:

MotionLayout is a subclass of ConstraintLayout and offer a mix of features between the property animation framework, TransitionManager, and CoordinatorLayout.

所以,我们可以把 MotionLayout 当做拥有对子控件声明并执行动画的 ConstraintLayout。

那,系统是如何让 MotionLayout 拥有这个能力的? 分别需要了解:

  • MotionScene
  • Transition
  • ConstraintSet
  • Constraint

从使用的角度,分别介绍它们。

使用步骤:

引入此库, 不做赘述,详见官网

声明 MotionLayout

  • 对已有根布局为 ConstraintLayout 的xml, 在 design 模式中,右键呼出菜单,选择 Covert MotionLayout.
  • 按照普通 ViewGoup 声明即可。
<?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">

    <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>

你应该发现了,上诉描述中的layoutDescription比较陌生,这个属性引用了 scene_01 . 这就是 'MotionScene'

MotionScene 其实是xml文件,下面我们就来看一眼声明的 scene_01.xml

<?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:constraintSetStartmotion:constraintSetEnd 分别定义动画开始和结束状态。这个状态通过 Constraint 定义。

<OnSwipe>定义触发动画的方式

Constraint 描述执行动画的控件的状态.在上述描述里,start 定义了 button 控件动画的起始的位置.end定义了结束的位置。不难发现,定义方式和使用约束布局是一样的。这大大降低了开发者们学习Constraint的成本。

  • ConstraintSet 通过组织 Constraint 完成多个控件执行动画。 我们还可以声明以下属性,完成更多的动画效果
    • alpha
    • visibility
    • elevation
    • rotation, rotationX, rotationY
    • translationX, translationY, translationZ
    • scaleX, scaleY

所以,当你想要不同的动画, 只需要在 Constraint 中定义你想要的状态,MotionLayout 会帮你平滑的过渡动画.

More

  • 可以拿到MotionLayout 对象即可调用相关方法.
  • Motion Editor 通过可视化界面,可让你享受所见即所得的动画制作过程。

参考