本文是对Introduction to MotionLayout的翻译,本身可能翻译的有点很差,欢迎你们批评指正。侵权删。php
MotionLayout是一个在ConstraintLayout2.0版本库的时候添加的一个新的类,能够帮助开发者处理一些动画。android
Android framework已经提供了如此多的方式来帮咱们在应用中添加动画,app
那么MotionLayout与它们有什么不一样的地方?ide
当想要对与用户有直接交互的UI元素作动画时。布局
什么是对与用户有着直接交互的UI元素?就是用户的点击,滑动等动做。gradle
dependencies {
implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha2'
}
复制代码
MotionLayout是ConstraintLayout的子类。要想已有的ConstraintLayout变成MotionLayout只须要在具体的xml中,将:动画
<android.support.constraint.ConstraintLayout .../>
复制代码
改为google
<android.support.constraint.motion.MotionLayout .../>
复制代码
MotionLayout动画的具体的描述文件并无包含在定义MotionLayout的layout文件中,而是定义在了一个单独的xml文件(一个MotionScene
文件)。spa
就如同以前所说,描述MotionLayout的动画的具体信息被定义在了一个单独的xml文件,MotionScene,一般存储在res/xml
目录下翻译
如图所述,一个MotionScene一般包含以下的内容
就像下面的例子,咱们经过使用手指拖动一个简单的view从屏幕的一端滑动至另外一端,如何作到呢?
一个指向初始的layout(view在屏幕左端),一个指向结束的layout(view在屏幕的右端),咱们须要定义两个layout
view在左端的layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent">
<View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
复制代码
view在右端的layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent">
<View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
复制代码
而后定义一个MotionLayout文件
<?xml version="1.0" encoding="utf-8"?>
<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>
复制代码
注意这个layout文件指向了一个MotionScene文件---scene_01
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition motion:constraintSetStart="@layout/motion_01_cl_start" motion:constraintSetEnd="@layout/motion_01_cl_end" motion:duration="1000">
<OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" />
</Transition>
</MotionScene>
复制代码
scene_01
经过指定开始和结束的ConstraintSet(motion_01_cl_start
和motion_01_cl_end
,规定了过渡动画。注意,咱们指定了OnSwipe
标签在transition中
在scene_01.xml
文件中,咱们指定了一个OnSwipe
标签,在一个Transition
标签中,做用是依据咱们的手指的动做,来让动画发生。
OnSwipe
的具体的各类属性
touchAnchorId
:咱们想要作动画的object对象,(这里是@+id/button
)
touchAnchorSide
:object的边,(right/left/top/bottom)
dragDirection
:咱们所想要追踪的手指动做的方向(dragRight/dragLeft/dragUp/dragDown)
第一种实现方式重用了layout(基于ConstraintLayout)
MotionLayout一样支持直接在MotionScene中定义ConstraintSets,这带来了以下优点:
让咱们将ConstraintSets直接定义在MotionScene中,达到和实现1同样的效果
咱们定义一个与实现1中同样的MotionLayout文件,只须要引用scene_02.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" app:layoutDescription="@xml/scene_02" android:layout_width="match_parent" android:layout_height="match_parent">
<View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:text="Button" />
</android.support.constraint.motion.MotionLayout>
复制代码
在scene_02.xml
中,Transition
标签内部是一致的,区别在于咱们直接将start
和end
的Constrait定义在了文件中。并由一个ConstraintSet
标签包含着。
<?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>
复制代码
在Constraint标签中除了能够定义元素的位置以外,还能够定义一些其余的属性,MotionLayout将自动地为这些属性生成中间的过渡状态,也就是插值。
alpha
visibility
elevation
rotation,rotation[x / y]
translation[x / y / z]
scaleX / Y
相似于下面的形式
<Constraint android:id="@id/content" android:layout_width="0dp" android:layout_height="match_parent" motion:layout_constraintWidth_default="percent" motion:layout_constraintWidth_percent="1" android:scaleX="0.8" android:scaleY="0.8" motion:layout_constraintLeft_toRightOf="@+id/button" motion:layout_constraintTop_toTopOf="parent"/>
复制代码
MotionLayout提供了一些属性
app:layoutDescription="reference"
,指向一个MotionScene XML文件
app:applyMotionScene="boolean"
是否使用MotionScene,默认为true
app:showPaths="boolean"
展现motion 路径,默认为false,app正式发布的时候要记得关闭
app:pregress="float"
明确指定中间进度,区间在0到1
app:currentState="reference"
强制一个特定的ConstraintSet
这篇文章只是MotionLayout的基础的功能的一个介绍,MotionLayout可以实现的功能远不止如此。