MotionLayout
是ConstrainLayout 2.0
库中被引入的一个新类,帮助安卓开发者关联手势和组件动画。接下来的文章将介绍会如何在应用中添加和使用MotionLayout
。java
第一章将介绍MotionLayout的基础:android
MotionLayout
是什么?ConstrainLayout 2.0
和MotionLayout
添加到项目中MotionLayout
ConstraintSets
MotionScene
你能够在这里查看示例的源码ConstraintLayout examples github repositorgit
安卓系统框架中已经提供下面几种方法在应用中使用动画:github
这一部分将介绍MotionLayout
与这些动画的不一样。MotionLayout
就像它的名字同样,首先它是一个布局,能够放置组件。其次它仍是ConstrainLayout
的子类,内置丰富的功能。建立MotionLayout
的目的是用于下降布局过渡动画和复杂的手势处理之间的难度,你能够认为它拥有综合属性动画TransitionManager
,和CoordinatorLayout
的功能。面试
它拥有综合属性动画TransitionManager
,和CoordinatorLayout
的功能
使用MotionLayout
你能够像TransitionManager
同样经过两个布局文件描述布局的过渡动画,可是可使用任何属性(不只仅局局于布局属性)。还有它支持可循迹的过渡,就像CoordinatorLayout
(能够经过滑动即刻响应过渡动画)。它支持经过滑动和关键帧自定义过渡动画。架构
MotionLayout
的另一个关键区别是,它是彻底声明式的。只须要XML文件就能够描述一个复杂的过渡动画(若是你像经过代码来描述动画,系统提供的属性彻底能够知足需求)。app
咱们相信这种声明式的规范将简化过渡动画,同时也有助于为 Android Studio 提供更好的图形化工具。(咱们如今正在积极的开发这样的工具,它如今还不可用。)框架
最后,做为ConstrainLayout 2.0的一部分,它最低支持安卓API 14,99.8%的设备均可以使用。ide
不一样于TransitionManager
,MotionLayout
只能用于他的直接子组件。工具
咱们设想到的使用MotionLayou
t的使用场景:当你须要移动,缩放或者动画实际的UI组件(按钮,标题栏等)来提供与用户的互动时。
将ConstrainLayout 2.0和MotionLayout添加到项目中,只须要将下面的代码添加到Gradle文件中便可
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1' }
MotionLayout
是ConstrainLayout
的子类,所以你能够把它看成一个普通的布局。将已经存在的ConstrainLayout
布局转换成MotionLayout
布局只须要将类名从:
<android.support.constraint.ConstraintLayout .../>
替换成
<android.support.constraint.motion.MotionLayout .../>
ConstrainLayou
t和MotionLayout
的主要不一样是MotionLayout
不是必须将实际描述信息包含在XML布局文件中。MotionLayout
一般将这些信息保存在一个单独的XML文件(MotionScene
)中并关联到布局文件,经过这种方式布局文件只须要包含它们的属性,无需包含位置信息和动画。
一般ConstrainSet
将全部游戏布局文件中的全部的位置信息规则; 你可使用多个ConstrainSet
,你能够决定将那些规则应用到布局中,在应用时这些查看不会被重建,只会修改他们的位置和大小。结合TransitionManager
使用能够很容易的建立ConstrainLayout
的动画。MotionLayout
实际上也是源于这种思想,并添加了更丰富的功能。
MotionLayout
的规范保存在一个单独的MotionScene
XML文件中,文件该存储在res / xml
目录中。
一个MotionScene
文件能够全部游戏动画所需的所用内容:
ConstraintSets
ConstraintSet
之间的转换(过渡)例如,你能够将一个查看从屏幕的一侧拖拽到另外一侧:
须要你使用ConstrainLayout
建立³³两个ConstrainSet
一个的英文初始位置(组件在屏幕的左面)一个是结束位置(组件在屏幕的右边)
初始位置:
<?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>
结束位置:
<?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>
使用这两个布局文件能够初始化两个ConstrainSet
,并使用他们(使用若是TransitionManager
会有动画的平滑过渡)。这种方式有一个问题是转化一旦开始就不会结束,你也不能告诉系统将转换挺在某个位置(你不能经过输入事件控制转换)。MotionLayout
解决了这些问题。你可使用MotionLayout
作一样的事,而且复用已存在的布局文件来初始化状态。首先须要为组件建立一个MotionLayout
文件(motion_01_basic.xml
):
<?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" 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" tools:layout_editor_absoluteX="147dp" tools:layout_editor_absoluteY="230dp" /> </androidx.constraintlayout.motion.widget.MotionLayout>
文件布局引用中了一个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
设置了默认的转换,设置了开始和结束ConstrainSet
(motion_01_cl_start
和motion_01_cl_end
),并转换为设置了OnSwipe
处理。
在scene_01.xml
文件中咱们在Transition
中设置了OnSwipe
处理器。处理器经过匹配用户的输入事件控制转换。
有一些属性你须要了解:
touchAnchorId
:须要跟踪的对象touchAnchorSide
:跟踪手指的一侧(右/左/上/下)dragDirection
:跟踪手指运动的方向(dragRight / dragLeft / dragUp / dragDown将决定进度值的变化0-1)示例1展现了如何快速的建立一个MotionLayout
。,使用名单最终已了存在的布局文件MotionLayout
还请当即获取iTunes直接在MotionScene
文件中定义ConstraintSet
。这样作有有如下好处:
ConstraintSet
MotionScene
中文件ConstraintSet
元素可使用的属性不只全部游戏经常使用的布局属性,位置除了状语从句:边距下面的属性也。能够在MotionLayout
中使用:
alpha visibility elevation rotation, rotation[X/Y] translation[X/Y/Z] scaleX/Y
让咱们为示例1从新建立一个新的自包含的MotionScene
。文件MotionLayout
文件除了引用了新的scene_02.xml
状语从句:实例1中没有区别:
<?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>
MotionScene
文件中有明显的区别,Transition
的设置相同,可是咱们把Start
和结束直接定义在了XML文件中。和普通布局文件相比主要的区别是咱们没有指定具体的组件,而是把限定属性写在了Constraint
元素中。
<?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>
只须要将了解ConstrainSet
是如何工做的,新的属性将替换到关联的组件上。只需将须要替换的属性所有包含到Constraint
中。一般这会清除组件上的所用属性并将新的属性赋值到组件上。MotionLayout
的属性
开发在中你可能会用到MotionLayout
的下列属性:
app:layoutDescription=”reference”
指定MotionScene
XML文件app:applyMotionScene=”boolean”
是否应用MotionScene [default = true]app:showPaths=”boolean”
是否显示路径[default = false]。记得在发布版本中关闭app:progress=”float”
指定转换的进度[0-1]app:currentState=”reference”
指定一个ConstraintSet第一篇文章包含了MotionLayout
的基础功能,你能够在这里查看源码:https://github.com/googlesamples/android-ConstraintLayoutExamples
接下来的文章中咱们将包含更多的讲解: