1、前语
最近在开发中,搭档竟然对MontionLayout
一知半解,那怎么行!百里偷闲写出此文章,一起学习、一起前进。假如写的不好,或许有过错之处,恳请在谈论、私信、邮箱指出,万分感谢
期望你在阅览这篇文章的时分,现已对下面的内容熟练掌握了
- Animated Vector Drawable
- Property Animation framework
- LayoutTransition animations
- Layout transitions with TransitionManager
对了还有ConstraintLayout有必要熟练掌握
对了,假如可以,请跟随敲代码,毕竟你脑补的代码,没有编译器。
当然你也可以阅览我的上一篇文章
- 5分钟带你学会MotionLayou 第一篇
- 5分钟带你学会MotionLayou 第二篇
2、OnSwipe、OnClick
同学们或许发现了,在上篇文章中,咱们运用了两个交互动作OnSwipe
和OnClick
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
<OnSwipe
motion:dragDirection="dragEnd"
motion:touchAnchorId="@+id/button1"
motion:touchAnchorSide="end" />
<!--OnClick 用于处理用户点击事情 -->
<!--targetId 设置触发点击事情的组件 -->
<!--clickAction 设置点击操作的呼应行为,这里是使动画过渡到完毕状况 -->
<OnClick
motion:clickAction="transitionToEnd"
motion:targetId="@+id/button1" />
</Transition>
这两位直面意思便是点击事情和滑动事情,OnClick的特点是十分简练的,由于仅仅个点击事情而已
-
targetId
:点击事情要运用的视图 ID。 -
clickAction
:界说点击事情的行为,可以有以下几种取值:-
toggle
:切换视图的状况。 -
transitionToEnd
:将视图从当时方位过渡到完毕方位。 -
transitionToStart
:将视图从当时方位过渡到开端方位。 -
jumpToEnd
:立行将视图移动到完毕方位。 -
jumpToStart
:立行将视图移动到开端方位。
-
OnSwipe的话,特点就比较多,可是都很直白,各位直接看看,需求用的时分找一找,多用用多看看就记住啦。
-
dragScale
:界说拖拽操作的缩放比例。这个特点通常用于完成一些扩大缩小的作用,可以让用户经过手势对视图进行缩放。 -
dragThreshold
:界说拖拽的最小阈值,当拖拽间隔小于该值时,视图不会呼应拖拽事情。这个特点可以用于操控视图呼应拖拽事情的灵敏度。 -
autoCompleteMode
:界说主动完结的形式,可以有以下两种取值:-
continuousVelocity
:运用连续的速度主动完结。 -
spring
:运用绷簧作用主动完结。
-
-
maxVelocity
:界说最大速度,当拖拽速度超越该值时,视图将不再呼应拖拽事情。 -
maxAcceleration
:界说最大加速度,当拖拽加速度超越该值时,视图将不再呼应拖拽事情。 -
springMass
:界说绷簧质量。 -
springStiffness
:界说绷簧刚度。 -
springDamping
:界说绷簧阻尼。 -
springStopThreshold
:界说绷簧中止的阈值,当速度小于该值时,绷簧将中止弹动。 -
springBoundary
:界说绷簧鸿沟,可以有以下几种取值:-
overshoot
:超出鸿沟时绷簧会继续弹动。 -
bounceStart
:当拖拽到开端方位时绷簧会弹动。 -
bounceEnd
:当拖拽到完毕方位时绷簧会弹动。 -
bounceBoth
:当拖拽到开端或完毕方位时绷簧会弹动。
-
-
dragDirection
:界说拖拽方向,可以有以下几种取值:-
horizontal
:只能水平拖拽。 -
vertical
:只能笔直拖拽。 -
both
:可以水平和笔直拖拽。
-
-
touchAnchorId
:界说接触点的锚定视图 ID。 -
touchAnchorSide
:界说接触点在锚定视图中的方位,可以有以下几种取值:-
top
:接触点坐落锚定视图的顶部。 -
bottom
:接触点坐落锚定视图的底部。 -
left
:接触点坐落锚定视图的左侧。 -
right
:接触点坐落锚定视图的右侧。 -
center
:接触点坐落锚定视图的中心。
-
-
rotationCenterId
:界说旋转中心的视图 ID。 -
touchRegionId
:界说接触区域的视图 ID。 -
limitBoundsTo
:界说限制鸿沟的视图 ID。 -
nestedScrollFlags
:界说嵌套翻滚的标志位,可以有以下几种取值:-
none
:不支撑嵌套翻滚。 -
disablePostScroll
:制止翻滚完毕后的翻滚。 -
disableScroll
:制止翻滚。 -
supportScrollUp
:支撑向上翻滚。
-
-
moveWhenScrollAtTop
:界说是否在翻滚到顶部时答应拖拽。 -
onTouchUp
:界说当手指离开屏幕时的行为,可以有以下几种取值:-
autoComplete
:主动完结拖拽。 -
autoCompleteToStart
:主动完结拖拽并回到开端方位。 -
autoCompleteToEnd
:主动完结拖拽并回到完毕方位。 -
stop
:中止拖拽。 -
decelerate
:减速拖拽。 -
decelerateAndComplete
:减速拖拽并完结拖拽。 -
neverCompleteToStart
:永久不要主动完结到开端方位。 -
neverCompleteToEnd
:永久不要主动完结到完毕方位。
-
关于绷簧作用,单纯是为了愈加天然。
以上便是两个的全部(部分?)特点啦,假如你需求更详细的了解,你可以在MotionLayout的资源目录中找到。
3、KeyFrameSet
在输入<符号时,弹出的三个提示,前面两个咱们现已了解了。那么第三个KeyFrameSet
是什么意思呢。
在一些情况下,您或许期望在转化视图状况时,具有中间状况,即一个需求经过但不需求逗留的状况。您可以指定多于两个 ConstraintSet,但更轻量的办法是运用 Keyframes。
在束缚布局中运用 Keyframes,需求界说一个 KeyPosition
方针和一个 KeyAttribute
方针。KeyPosition
方针界说了中间状况的方位,KeyAttribute
方针界说了中间状况的特点值。您可以将多个 KeyPosition
和 KeyAttribute
方针组合成一个 Keyframes
方针,并将其运用于束缚布局中的任何特点。
fragment_motion_04_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/ml_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_layout_04_scene"
tools:showPaths="true">
<View
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:background="@color/orange"
android:text="Button"/>
<View
android:id="@+id/button2"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:background="@color/orange"
android:text="Button" />
</androidx.constraintlayout.motion.widget.MotionLayout>
motion_layout_04_scene.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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000"
motion:motionInterpolator="linear">
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorId="@+id/button1"
motion:touchAnchorSide="right" />
<KeyFrameSet>
<KeyPosition
motion:framePosition="25"
motion:keyPositionType="pathRelative"
motion:motionTarget="@+id/button1"
motion:percentY="0.1" />
<KeyPosition
motion:framePosition="75"
motion:keyPositionType="pathRelative"
motion:motionTarget="@+id/button1"
motion:percentY="-0.1" />
</KeyFrameSet>
<KeyFrameSet>
<KeyPosition
motion:framePosition="25"
motion:keyPositionType="pathRelative"
motion:motionTarget="@+id/button2"
motion:percentY="0.3" />
<KeyPosition
motion:framePosition="75"
motion:keyPositionType="pathRelative"
motion:motionTarget="@+id/button2"
motion:percentY="-0.3" />
<KeyAttribute
android:scaleX="2"
android:scaleY="2"
android:rotation="-45"
motion:framePosition="50"
motion:motionTarget="@id/button2" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="6dp"
motion:layout_constraintBottom_toTopOf="@id/button2"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/button2"
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_toBottomOf="@id/button1" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toTopOf="@id/button2"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintHorizontal_bias="1"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="@+id/button2"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintHorizontal_bias="1"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/button1" />
</ConstraintSet>
</MotionScene>
作用如下啦。
KeyPosition
还有许多特点,大都都是一看就懂的特点
-
keyPositionType
:界说如何核算要害帧的误差。可以设置为deltaRelative
、pathRelative
或parentRelative
三种取值之一。运用deltaRelative
时,要害帧的误差相关于线性途径核算;运用pathRelative
时,要害帧的误差相关于途径核算;运用parentRelative
时,要害帧的误差相关于父视图核算。 -
percentX
、percentY
:界说要害帧在 X 和 Y 轴上的方位。可以设置为 0 到 1 之间的浮点数,表明从开端状况到完毕状况之间的相对方位。 -
percentWidth
、percentHeight
:界说宽度和高度的改变量。可以设置为 0 到 1 之间的浮点数,表明从开端状况到完毕状况之间的相对改变量。注意,假如宽度或高度没有改变,则这些特点将没有任何作用。 -
framePosition
:界说要害帧在动画中的方位。可以设置为 0 到 100 之间的整数,表明从动画开端到完毕之间的相对方位。 -
motionTarget
:界说运用此要害帧的运动方针。可以是一个视图或许一个运动场景。 -
transitionEasing
:界说要害帧的过渡缓动作用。可以运用 Android 体系中供给的各种缓动函数,比如easeIn
,easeOut
等。 -
pathMotionArc
:界说要害帧在途径上的运动方式。可以设置为none
、startVertical
、endVertical
、flip
或rotate
等五种取值之一。 -
curveFit
:界说要害帧的插值方式。可以设置为linear
、spline
或discrete
等三种取值之一。 -
drawPath
:界说是否在编辑器中制作要害帧途径。 -
sizePercent
:界说宽度和高度的百分比。可以设置为 0 到 1 之间的浮点数,表明相关于视图父级的百分比。
由于keyPositionType可以说许多,我会在后面的文章,继续展开。这里咱们只运用pathRelative
KeyAttribute
还有许多特点,大都都是一看就懂的特点
-
framePosition
:界说要害帧在动画中的方位。可以设置为 0 到 100 之间的整数,表明从动画开端到完毕之间的相对方位。 -
motionTarget
:界说运用此要害帧的运动方针。可以是一个视图或许一个运动场景。 -
transitionEasing
:界说要害帧的过渡缓动作用。可以运用 Android 体系中供给的各种缓动函数,比如easeIn
,easeOut
等。 -
curveFit
:界说要害帧的插值方式。可以设置为linear
、spline
或discrete
等三种取值之一。 -
motionProgress
:界说要害帧的运动进展,即从开端状况到完毕状况之间的进展百分比。 -
alpha
:界说视图的不透明度。可以设置为 0 到 1 之间的浮点数,表明视图的透明度。 -
elevation
:界说视图的高度。可以设置为一个浮点数,表明视图的高度。 -
rotation
、rotationX
、rotationY
:界说视图的旋转视点,可以别离设置 X、Y、Z 轴上的旋转视点。 -
transformPivotX
、transformPivotY
:界说视图的改换中心点坐标。 -
transformPivotTarget
:界说改换中心点的方针视图。 -
transitionPathRotate
:界说视图在途径上的旋转视点。 -
scaleX
、scaleY
:界说视图的缩放比例。 -
translationX
、translationY
、translationZ
:界说视图的方位偏移量。
4、CustomAttribute
假如仅仅只能动画化咱们之前提过的特点,那么MotionLayout
只会显得过于单调,而假如经过代码去动态修改某些状况,那就体现不出MotionLayout
的优势了。
所以CustomAttribute
一个自界说特点调集,用于将自界说特点运用于视图或运动场景。运用 CustomAttribute
,您可以将任何自界说特点与束缚布局中的其他特点结合运用,从而完成愈加杂乱和灵活的布局作用。
CustomAttribute
自界说特点调集中的一些要害特点:
-
attributeName
:界说自界说特点的称号。。 -
customColorValue
:界说自界说颜色值。可以设置为一个整数,表明颜色值。 -
customDimension
:界说自界说尺度值。可以设置为一个浮点数,表明尺度值。 -
customFloatValue
:界说自界说浮点数值。可以设置为任何浮点数。 -
customIntegerValue
:界说自界说整数值。可以设置为任何整数。 -
customStringValue
:界说自界说字符串值。可以设置为任何字符串。
咱们来试一下
fragment_motion_05_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/ml_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_layout_05_scene"
tools:showPaths="true">
<View
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:background="@color/orange"
android:text="Button"
app:layout_constraintBottom_toTopOf="@id/button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/button2"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:src="@mipmap/icon_menu_emoticon1"
app:altSrc="@mipmap/icon_menu_emoticon3"
android:text="Button"
app:layout_constraintBottom_toTopOf="@id/button3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button1" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/button3"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:src="@mipmap/icon_menu_emoticon2"
android:text="Button"
app:layout_constraintBottom_toTopOf="@id/button4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button2" />
</androidx.constraintlayout.motion.widget.MotionLayout>
motion_layout_05_scene.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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
<!--OnClick 用于处理用户点击事情 -->
<!--targetId 设置触发点击事情的组件 -->
<!--clickAction 设置点击操作的呼应行为,这里是使动画过渡到完毕状况 -->
<OnSwipe
motion:dragDirection="dragEnd"
motion:touchAnchorId="@+id/button1"
motion:touchAnchorSide="end" />
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toTopOf="@id/button2"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#D81B60" />
</Constraint>
<Constraint
android:id="@+id/button2"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toTopOf="@id/button3"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/button1">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
</Constraint>
<Constraint
android:id="@+id/button3"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toTopOf="@id/button4"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/button2" >
<CustomAttribute
motion:attributeName="saturation"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/button1"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toTopOf="@id/button2"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintHorizontal_bias="1"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#9999FF" />
</Constraint>
<Constraint
android:id="@+id/button2"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toTopOf="@id/button3"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintHorizontal_bias="1"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/button1">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
</Constraint>
<Constraint
android:id="@+id/button3"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toTopOf="@id/button4"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintHorizontal_bias="1"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toBottomOf="@id/button2" >
<CustomAttribute
motion:attributeName="saturation"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
</MotionScene>
值得注意的是
自界说特点的称号有必要与View具有相应的setter办法称号相匹配,才能在MotionLayout中运用。例如,假如您想要界说一个名为”customText”的CustomAttribute来操控TextView的文本内容,那么TextView中需求有一个名为为”setCustomText”的办法,以便MotionLayout可以找到相应的setter办法。
因此,只要View具有相应的setter办法的自界说特点才能被运用。假如您想要运用一个View没有的特点,您需求创建一个新的自界说View并完成相应的setter和getter办法。
5、下个华章
由于篇幅原因,咱们先到这,下一篇咱们将会深化了解各种运用事例~。
假如您有任何疑问、对文章写的不满意、发现过错或许有更好的办法,欢迎在谈论、私信或邮件中提出,十分感谢您的支撑。
6、感谢
- 校稿:ChatGpt
- 文笔优化:ChatGpt