MotionLayout不断地更新,文章并不适用全部最近的更新内容。
文章目录
引入
MotionLayout是Android支持库中的一个布局容器,它可以帮助实现复杂的界面动画和过渡效果。MotionLayout结合了ConstraintLayout和MotionScene的功能,可以通过定义关键帧和过渡效果来创建各种复杂的动画效果。
ConstraintSet
- 
创建和应用约束关系: - ConstraintSet constraintSet = new ConstraintSet(): 创建一个新的ConstraintSet对象。
- constraintSet.clone(ConstraintLayout layout): 从一个ConstraintLayout中克隆约束关系到ConstraintSet对象中。
- constraintSet.applyTo(ConstraintLayout layout): 将ConstraintSet对象中的约束关系应用到指定的ConstraintLayout中。
 
- 
添加和修改约束关系: - constraintSet.connect(int startID, int startSide, int endID, int endSide, int margin): 添加两个视图之间的连接关系,并指定连接的边和边距。
- constraintSet.setHorizontalBias(int viewId, float bias): 设置视图在水平方向上的偏移位置。
- constraintSet.setVerticalBias(int viewId, float bias): 设置视图在垂直方向上的偏移位置。
- constraintSet.constrainHeight(int viewId, int height): 设置视图的高度。
- constraintSet.constrainWidth(int viewId, int width): 设置视图的宽度。
- constraintSet.setVisibility(int viewId, int visibility): 设置视图的可见性。
 
- 
移除约束关系: - constraintSet.clear(int viewId): 移除指定视图的所有约束关系。
- constraintSet.clear(int viewId, int anchor): 移除指定视图与指定锚点视图之间的约束关系。
 
我们可以使用 ConstraintSet 和 TransitionManager 来实现一个平移动画。
TransitionManager和MotionLayout有什么区别?
ransitionManager和MotionLayout是Android中用于实现动画效果的两个不同的类。
TransitionManager是Android提供的一个类,用于管理场景之间的转换和动画效果。它可以在不同的ViewGroup之间实现平滑的过渡动画,例如在切换布局、添加或移除View时的过渡效果。TransitionManager通过场景(Scene)的概念来管理动画,可以定义多个不同的场景,并在场景之间进行转换。
MotionLayout是一个继承自ConstraintLayout的布局容器,它可以用来实现复杂的动画和过渡效果。MotionLayout基于ConstraintSet和Transition的概念,通过定义起始和结束状态的约束集合(ConstraintSet),再结合过渡效果(Transition)来实现布局的动画过渡。与TransitionManager相比,MotionLayout提供了更强大和灵活的动画控制能力,可以实现更复杂的动画效果,例如更精细的属性动画、路径动画、关键帧动画等。
当需要简单的场景过渡效果,例如在切换布局或添加/移除View时的平滑过渡,可以使用TransitionManager。而当需要实现更复杂、精细的动画效果时,例如属性动画、路径动画等,可以选择使用MotionLayout。 MotionLayout相对于TransitionManager来说功能更加强大,但也更复杂一些,需要更多的配置和设置。因此,根据具体需求和复杂度来选择使用哪个类。
使用
在MotionLayout布局下每个控件都需要设置一个id
在xml根布局改成MotionLayout后,爆红,可利用编译器自动生成xml文件用来对应layoutDescription属性。该文件用来定义这个动画的动画过程和约束条件。
            
            
              xml
              
              
            
          
          layoutDescription="@xml/fragment_motion_01_basic_scene"打开该生成文件:

可以看到本质是MotionScene+ Transition,用于描述动画的动效。
- ConstrainSet描述了开始或结束时页面控件的状态
- Transtion指定了动画要使用的ConstrainSet,动画的触发方式等。
编译器已经自动生成了Start和End的ConstrainSet,那我们主要工作就是操作MotionScene+ Transition
ConstrainSet(属性类似于ConstrainLayout)
ConstraintSet是Android中的一个工具类,它用于在代码中动态设置和管理ConstraintLayout的约束关系。ConstraintLayout是一个强大的布局容器,可以实现复杂的界面布局,而ConstraintSet可以帮助我们在运行时修改和更新这些布局。
使用ConstraintSet,我们可以在不重新加载布局文件的情况下,通过代码来添加、修改或移除视图的约束关系,实现动态的布局效果。下面是一些ConstraintSet的常用方法和功能:
ConstrainSet下的标签类似于Constrainlayout的属性,我们可以直接内嵌Constrain,直接描述出Start和end的状态,再通过Transition进行动画效果的配置。
            
            
              xml
              
              
            
          
          <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ConstraintSet android:id="@+id/start">
        <Constraint android:id="@+id/button"
            android:background="@color/orange"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"  />
    </ConstraintSet>
    <ConstraintSet android:id="@+id/end">
        <Constraint  android:id="@+id/button"
            android:background="@color/orange"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>
    <Transition
         ...
    </Transition>
</MotionScene>Transition
属性
- app:constraintSetStart:指定过渡的起始状态的ConstraintSet。可以使用- @id引用已定义的ConstraintSet。
- app:constraintSetEnd:指定过渡的结束状态的ConstraintSet。同样也可以使用- @id引用已定义的ConstraintSet。
- app:duration:指定动画过渡的持续时间,单位为毫秒。
- app:staggered:在多个View之间应用过渡效果时,指定是否应该依次进行过渡。可以设置为- true或- false。
- app:autoTransition:指定是否在布局文件加载时自动开始过渡动画。可以设置为- startToEnd、- endToStart、- autoTransition。
- app:cycleDuration:指定循环过渡的总时间。当使用循环过渡时,可以设置循环的总时间。
- app:transitionOnBackward:指定当用户反向滑动时是否触发过渡动画。可以设置为- normal、- jumpToEnd或- jumpToStart。
- app:transitionDisable:指定是否禁用过渡动画。可以设置为- true或- false。
- app:motionInterpolator:指定过渡动画的插值器。可以设置为- linear、- accelerate、- decelerate、- fast_out_linear_in、- fast_out_slow_in等。
- app:pathMotionArc:指定过渡动画中路径的弧度。可以设置为- none、- startVertical、- endVertical、- startHorizontal、- endHorizontal等。
- app:touchAnchorId:指定触摸点的锚点View的ID。在触摸事件中,可以定义触摸点锚定的位置。
定义的可处理事件有以下三种,用来规定用户交互逻辑详细法则。

OnClick
在Transition中,可以定义OnClick标签用于处理用户点击事件,
            
            
              xml
              
              
            
          
                  <OnClick
            motion:clickAction="toggle"
            motion:targetId="@+id/button" />
        <!--OnClick 用于处理用户点击事件 -->
        <!--targetId 设置触发点击事件的组件 -->
        <!--clickAction 设置点击操作的响应行为,这里是使动画过渡到结束状态 -->- 
app:clickAction="toggle":点击时切换到指定的ConstraintSet。例如, app:clickAction="@id/secondConstraintSet"表示点击时切换到ID为secondConstraintSet的ConstraintSet。
- 
app:clickAction="jumpToEnd":点击时立即跳转到Transition的结束状态。
- 
app:clickAction="jumpToStart":点击时立即跳转到Transition的开始状态。
- 
app:clickAction="none":点击时不执行任何操作,保持当前状态不变。
- 
app:clickAction="transitionToEnd":点击时执行Transition到结束状态的动画。
- 
app:clickAction="transitionToStart":点击时执行Transition到开始状态的动画。
- 
app:clickAction="transitionWithCrossfade":点击时执行Transition到指定ConstraintSet的动画,并添加淡入淡出效果。
OnSwipe
OnSwipe一般用于处理拖拽事件,其中有一个弹簧的理念。
- 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:永远不要自动完成到结束位置。
 
KeyFrameSet
KeyFrameSet(关键帧集合)是在动画中定义和控制关键帧的一种方式。通过使用KeyFrameSet,可以定义动画的起始和结束状态 ,控制动画的过程和插值方式 ,实现多阶段动画

需要定义一个 KeyPosition 对象和一个 KeyAttribute 对象。
KeyPosition 对象定义了中间状态的位置,KeyAttribute 对象定义了中间状态的属性值。您可以将多个 KeyPosition 和 KeyAttribute 对象组合成一个 Keyframes 对象,并将其应用于约束布局中的任何属性
KeyPosition
            
            
              java
              
              
            
          
          <KeyPosition
    time="1000"               // 时间点,单位为毫秒
    position="0, 0, 0"        // 位置坐标,可以是二维或三维坐标
    interpolation="linear"    // 插值方式,例如线性插值
    easing="ease-in-out"      // 缓动效果,例如渐入渐出
/>- 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 之间的浮点数,表示相对于视图父级的百分比。
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:定义视图的位置偏移量。
CustomAttribute
CustomAttribute是一种用于自定义属性的元素。它允许你在布局文件中定义和使用自定义属性,以便在MotionScene中使用这些属性来控制动画效果。你可以在MotionLayout中设置一个起始状态和一个结束状态,然后使用CustomAttribute来设置自定义属性在这两个状态之间的过渡效果。
            
            
              xml
              
              
            
          
          <CustomAttribute
    app:attributeName="customProperty"  // 自定义属性的名称
    app:customDimension="100dp"         // 自定义属性的值
    />属性
- app:attributeName: 定义自定义属性的名称。
- app:customColorValue: 设置自定义属性的颜色值,例如- #FF0000表示红色。
- app:customDimension: 设置自定义属性的尺寸值,例如- 100dp表示100个设备独立像素。
- app:customFloatValue: 设置自定义属性的浮点数值。
- app:customIntValue: 设置自定义属性的整数值。
- app:customStringValue: 设置自定义属性的字符串值。
自定义属性的名称必须与View具有相应的setter方法名称相匹配,才能在MotionLayout中使用。例如,如果您想要定义一个名为"customText"的CustomAttribute来控制TextView的文本内容,那么TextView中需要有一个名为为"setCustomText"的方法,以便MotionLayout能够找到相应的setter方法。