What is MotionLayout?
MotionLayout
is a layout type that helps you manage motion and widget animation in your app.MotionLayout
is a subclass ofConstraintLayout
and builds upon its rich layout capabilities. As part of theConstraintLayout
library,MotionLayout
is available as a support library and is backwards-compatible to API level 14.
MotionLayout
bridges the gap between layout transitions and complex motion handling, offering a mix of features between the property animation framework,TransitionManager
, andCoordinatorLayout
.引用自官方文档:Manage motion and widget animation with MotionLayout
通过阅读官方文档我们可以得知MotionLayout
的一些信息:
MotionLayout是用来帮助开发者管理运动和组件动画的
MotionLayout是ConstraintLayout的子类
MotionLayout是ConstraintLayout 2.0库中提供的新类,也可作为支持库使用,并且向后兼容到API 14。
MotionLayout是为了弥合了布局过渡和复杂运动处理之间的鸿沟,在属性动画框架,TransitionManager和CoordinatorLayout之间提供了多种功能。
MotionLayout是完全声明式,我们可以用xml描述出任何复杂的效果
MotionLayout不支持嵌套子布局或者activity transition(如果您就有这样的需求,那还是乖乖的用TransitionManager吧)
-
最后,官方建议不要把MotionLayout仅仅当做一个动效库来使用,它应该用于帮助用户了解您的应用程序在做什么,并表达品牌的个性和风格。
When to use it?
当我们学习一个新的东西的时候,“什么时候(情况下)使用它?”是一个很重要的问题。如果这个问题没想清楚,可能会引发一些不良的效果。
那么,什么时候去用MotionLayout呢?
Use MotionLayout when animating UI elements the user will interact with
当用户需要与有动效的UI元素交互时请使用MotionLayout
言外之意:
- 现有实现动效的方式就可以简单实现的就别折腾了,比如用以下方式
- 一些界面加载完就直接执行的复杂动画,直接用Gif或者视频搞定的也不需要
- 总结一下,别为了用MotionLayout而强行使用
Getting started
在开始使用MotionLayout之前我们需要准备以下几步。
1. Android Studio 4.0
MotionLayout编辑器仅支持4.0之上版本
2. 导入依赖
在您app的build.gradle
文件添加ConstraintLayout 2.0
的依赖。
如果你使用的是AndroidX
dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3' }
-
如果你还没有迁移到AndroidX,则需要使用support 库
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta3' }
3. 创建布局文件
创建完fragment_explore_motion_layout_part1.xml
布局文件后,在Design模式下,右键点击布局或者Component Tree
,选择菜单中的Convert to MotionLayout
选项即可一步将布局转换为MotionLayout
。
我们再来看一下该布局的xml代码
为了使布局信息与运动描述分开,每个MotionLayout都会使用app:layoutDescription
引用一个单独的MotionScene文件,这个文件放在res/xml
文件夹。
下面来看一下生成的MotionScene文件:res/xml/fragment_explore_motion_layout_part1_scene.xml
4. MotionScene常见的标签及属性
-
Transition
标签是用来定义运动的具体细节的常用的如下
-
constraintSetStart
定义运动的初始状态这可以是
ConstraintSet
的ID,也可以是布局。要指定
ConstraintSet
,请将此属性设置为@+id/constraintSetId
。要指定布局,请设置为
@layout/layoutState
。 constraintSetEnd
定义运动的最终状态,取值同constraintSetStart
-
duration
定义运动的持续时间,以毫秒为单位,如不指定则使用默认值400ms
-
motionInterpolator
定义运动插补器- easeInOut 缓入缓出
- easeIn 缓入
- easeOut 缓出
- linear 线性
- bounce 弹跳效果
-
autoTransition
自动过渡- none 不运动
- jumpToStart 直接跳到开始
- jumpToEnd 直接跳到结束
- animateToStart 执行动画到开始
- animateToEnd 执行动画到结束
-
-
OnSwipe
指定用户在布局上滑动时要执行的操作。-
touchAnchorId
通过滑动移动的视图的Id。 -
touchAnchorSide
用户滑动界面时MotionLayout将尝试在touchAnchorId
指定的视图和用户手指之间保持恒定的距离。而此属性指定的是手指和view的那一侧保持恒定的距离,可取值有以下几个:- left
- right
- top
- bottom
-
dragDirection
用户滑动动作的方向。如果设置了此属性,则此onSwipe
仅适用于沿指定方向的滑动。可接受的值为- dragLeft 左滑
- dragRight 右滑
- dragUp 上滑
- dragDown 下滑
-
-
OnClick
指定当用户点击特定视图时要执行的操作。单个Transition
可以有多个OnClick
节点,每个OnClick
指定一个不同的目标视图,并在点击该视图时执行不同的操作。targetId
当用户点击targetId指定的view时将会执行Transition
-
ClickAction
点击视图时执行的操作。支持的值为:-
toggle
切换状态,如果当前状态是start的话,执行动画到end状态;若当前状态是end状态,则执行动画到start状态。
transitionToStart 执行动画到start状态
transitionToEnd 执行动画到end状态
jumpToStart 直接跳转到start状态
jumpToEnd 直接跳转到end状态
-
-
KeyFrameSet
指定运动序列过程中视图的位置和属性。默认情况下,运动会从初始状态进行到结束状态。通过使用<KeyFrameSet>,您可以构建更复杂的动作。 <KeyFrameSet>包含<KeyPosition>或<KeyAttribute>节点。这些节点中的每个节点都指定运动中特定点的目标视图的位置或属性。 MotionLayout从起点到这些中间点中的每一个,再到最终目的地,使视图平滑地动画化。
-
KeyPosition
指定运动序列中特定时刻的视图位置。此属性用于调整运动的默认路径。
-
motionTarget
要在运动过程中改变属性的视图的Id
-
framePosition
指定视图在运动序列中何时具有此<KeyAttribute>指定的属性。例如,
framePosition = 50
则代表视图运动到整个运动序列的50%处。 percentX
percentY
指定视图应到达的位置。这两个属性需要配合keyPositionType
才能确定具体位置。-
keyPositionType
指定如何解释percentX和percentY值。
-
parentRelative
percentX和percentY是相对于父视图指定的。取值范围 0~1。
-
deltaRelative
相对于视图在整个运动序列过程中移动的距离,指定了percentX和percentY。 X为横轴,Y为纵轴。在这两种情况下,0都是该轴视图的起始位置,而1是最终位置。
Note:deltaRelative模式下,x,y坐标范围不是0~1。
x<0 ----> 视图会定位到y轴的左侧。
y<0 ----> 视图会定位到x轴的下方。
x=1.5 ---> 代表视图定位到x轴方向start到end的横向距离1.5倍的位置
y=1.5 ---> 代表视图定位到y轴方向start到end的垂直距离1.5倍的位置
-
pathRelative
X轴是目标视图在路径范围内移动的方向,0为开始位置,1为最终位置。 Y轴垂直于X轴,正值位于路径的右侧,负值位于左侧;设置一个非零的Y百分比会导致视图的路径向X轴的左侧或者右侧偏转形成弧线。因此,视图的初始位置是(0,0),最终位置是(1,0)。
很多文章包括官网对y轴的取值都是写的x轴的左侧为正值,右侧为负值,但我实际测试的结果却是相反的。希望读者都亲自尝试一下。
-
-
-
KeyAttribute
指定运动序列中特定时刻的视图属性。您可以使用<KeyAttribute>设置视图的任何标准属性。
alpha
visibility
elevation
-
rotation
,rotationX
,rotationY
-
translationX
,translationY
,translationZ
-
scaleX
,scaleY
-
ConstraintSet
为一个或多个<Transition>节点指定开始或结束状态
关于更多的MotionScene标签以及它有哪些子标签可以查阅官方文档MotionLayout reference
Basic motion
下面这个栗子包含一个正方形的View,可以水平滑动。
MotionLayout
的motionDegbug属性可以开启调试模式
- motionDegbug
- SHOW_PATH 展示运动路径
- SHOW_PROGRESS 展示运动进度
- SHOW_ALL 展示PATH&PROGRESS
KeyPosition
在
framePosition=50
处向y轴方向偏移50%KeyAttribute
在
framePosition=50
处改变视图的如下属性:
- 整体缩放2倍
- X轴旋转-60°,y轴旋转45°
- 透明度变为0.3
Custom attribute
下面使用ImageFilterView来演示自定义属性
Note:请注意,指定自定义属性时,自定义属性必须在start和end的
ConstraintSet
元素中成对出现
,另外在运动过程中改变自定义属性时,也要保证前面的规则。
start中的初始自定义属性
roundPercent = 0.1
代表拥有10%的圆角取值范围[0~1],0代表正方形,1代表正圆。
crossfade = 0
展示src图片0=src,1=altsrc
end中的最终自定义属性
roundPercent = 1
正圆crossfade = 1
展示altsrc图片详情参见ImageFilterView
Summary
探索MotionLayout的Part1到此结束,本文主要介绍了一下MotionLayout是啥?啥时候用它?基础用法....
探索MotionLayout的Part2预计会实现一些更加复杂的效果。
关于本文顶部的效果参见MotionScene文件
Reference
原文链接:http://www.itzhouyang.com/post/explore_motion_layout_part1.html