探索 MotionLayout 动画世界

探索 MotionLayout 动画世界

先附上一个简单的动画效果图:

MotionLayout是什么 ?

MotionLayout是ConstraintLayout的子类,具有ConstraintLayout的所有功能。

一、使用步骤

1. 添加依赖
ini 复制代码
dependencies {
    implementation(libs.constraintlayout)
}

[versions]
constraintlayout = "2.1.4"

[libraries]
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
ConstraintLayout 的版本需要更新到2.0以上。
2. 创建布局

创建一个布局文件名为view_nav.xml根布局为ConstraintLayout。

xml 复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
        android:layout_height="match_parent">

        ......

    </androidx.constraintlayout.widget.ConstraintLayout>

然后将布局转换为MotionLayout,如下图。

转换之后布局如下:

xml 复制代码
    <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        app:layoutDescription="@xml/view_nav_scene">

        ......

    </androidx.constraintlayout.motion.widget.MotionLayout>

根布局会自动转换为MotionLayout并且添加了一个属性app:layoutDescription,这个属性所引用的文件就是我们要编写的动画描述文件。

转换之后在Design面板会多出一个预览窗口。

3. 创建动画资源文件

AndroidStudio自动为我们创建的MotionScene 文件如下:

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">
           <KeyFrameSet>
           </KeyFrameSet>
        </Transition>

        <ConstraintSet android:id="@+id/start">
        </ConstraintSet>

        <ConstraintSet android:id="@+id/end">
        </ConstraintSet>
    </MotionScene>

这也是一个MotionScene文件的基本结构。

  • ConstrainSet描述了开始或结束时页面控件的状态
  • Transtion指定了动画要使用的ConstrainSet,动画的触发方式等。

如果我们不使用AndroidStudio来转换布局为MotionLayout的话,就需要自己在res\xml文件夹下创建一个根节点为MotionScene的xml文件。

4. 预览

预览画面如下图所示:

点击箭头1所指的start可以预览动画start状态。 点击箭头2所指的end可以预览动画end状态。 点击箭头3所指的start和end之间的连线可以在下方的面板中点击播放查看动画。

二、MotionScene常用属性

1. MotionLayout标签
  • layoutDescription :设置布局的MotionScene文件。
  • applyMotionScene :表示是否应用 MotionScene。此属性的默认值为 true。
  • currentState :设置当前的状态,值对应MotionScene中的ConstraintSet节点的id。比如我们可以将其设置为@+id/end(结束状态)。
  • motionProgress :值为0到1之间的小数,用来设置页面开始时的动画进度。例如,将motionProgress设置为0.5,那么页面将以动画进行一半的状态开始。
  • showPaths :是否显示动画路径,为true话会显示view运动的轨迹线。
  • motionDebug :显示何种调试信息,设置的话会在界面的下方显示一些动画调试信息。

如果我们只设置了motion:showPaths="true"的话那么就会显示轨迹线,如果同时设置了motion:showPaths和motion:motionDebug的话,showPaths的设置会失效。以motionDebug的设置为准。

2. MotionScene标签
  • <Transition> :指定动画的开始和结束状态、触发动画的方式、动画中间的关键帧。
  • <ConstraintSet> :节点用来定义开始或是结束时控件的状态。我们需要在这个节点下重新为想要动画的控件进行布局。这里的设置会覆盖之前布局xml文件中的设置,可以将这个节点想象为ConstraintLayout布局,其中的子节点Constraint可以想象为每一个View,其中的android:id=""属性对应着原layout.xml中的view的id
  • defaultDuration:所有过渡动画的默认持续时间(以毫秒为单位)。
3. Transition标签
  • constraintSetStart :设置动画的开始状态,这里对应一个ConstraintSet的id。
  • constraintSetEnd :设置动画的结束状态,这里对应一个ConstraintSet的id。
  • duration :动画的持续时间,如果没有设置会使用MotionScene元素的defaultDuration。
  • staggered :在多个View之间应用过渡效果时,指定是否应该依次进行过渡。可以设置为true或false。
  • autoTransition :指定是否在布局文件加载时自动开始过渡动画。可以设置为
    • animateToStart :切换到开始状态,有动画效果。
    • animateToEnd :切换到结束状态,有动画效果。
    • jumpToStart :切换到开始状态,无动画效果。
    • jumpToEnd :切换到结束状态,无动画效果。
  • motionInterpolator :动画的差值器,其值为常用的几种效果bounce,easeIn,easeOut,easeInOut,linear。
  • transitionDisable :指定是否禁用过渡动画。可以设置为true或false。
  • pathMotionArc :指定过渡动画中路径的弧度。可以设置为none、flip、startVertical、startHorizontal。

Transition标签定义的可处理事件有三种:OnClickOnSwipeKeyFrameSet

4. OnClick

用于处理用户点击事件。

  • targetId :被点击后触发动画的视图id。
  • clickAction :点击时要执行的操作。
    • toggle :在transitionToStartconstraintSetEnd状态之间使用动画反复切换。每次点击从一种状态切换到另一种状态。
    • transitionToStart :从当前状态切换到 constraintSetStart 属性指定的状态,有动画效果。
    • transitionToEnd :从当前状态切换到 constraintSetEnd 属性指定的状态,有动画效果。
    • jumpToStart :从当前状态切换到 constraintSetStart 属性指定的状态,无动画效果。
    • jumpToEnd :从当前状态切换到 constraintSetEnd 属性指定的状态,无动画效果。
5. OnSwipe

用户处理用户拖拽事件。

  • touchAnchorId :可以滑动并拖动的视图id(目标视图)。
  • touchAnchorSide :定义触摸点在目标视图中的位置。
    • top :触摸点位于目标视图上方。
    • bottom :触摸点位于目标视图下方。
    • left/start :触摸点位于目标视图左方。
    • right/end :触摸点位于目标视图又方。
    • middle :触摸点位于目标视图中心。
  • dragDirection :拖拽的方向。
    • dragUp :上滑
    • dragDown :下滑
    • dragLeft/dragStart :左滑
    • dragRight/dragEnd :右滑
  • touchRegionId :触摸区域的视图id。
  • onTouchUp :手指离开屏幕时的行为。
    • autoComplete :自动完成拖拽。
    • autoCompleteToStart :自动完成拖拽并回到开始位置。
    • autoCompleteToEnd :自动完成拖拽并回到结束位置。
    • stop :停止拖拽。
    • decelerate :减速拖拽。
    • decelerateAndComplete :减速拖拽并完成拖拽。
    • neverCompleteToStart :永远不要自动完成到开始位置。
    • neverCompleteToEnd :永远不要自动完成到结束位置。
  • dragScale :定义拖拽操作的缩放比例。这个属性通常用于实现一些放大缩小的效果,可以让用户通过手势对视图进行缩放。
  • dragThreshold :定义拖拽的最小阈值,当拖拽距离小于该值时,视图不会响应拖拽事件。这个属性可以用于控制视图响应拖拽事件的灵敏度。
  • autoCompleteMode :定义自动完成的模式。
    • continuousVelocity :使用连续的速度自动完成。
    • spring :使用弹簧效果自动完成。
  • maxVelocity :定义最大速度,当拖拽速度超过该值时,视图将不再响应拖拽事件。
  • maxAcceleration :定义最大加速度,当拖拽加速度超过该值时,视图将不再响应拖拽事件。
  • springMass :定义弹簧质量。
  • springStiffness :定义弹簧刚度。
  • springDamping :定义弹簧阻尼。
  • springStopThreshold :定义弹簧停止的阈值,当速度小于该值时,弹簧将停止弹动。
  • springBoundary :定义弹簧边界,可以有以下几种取值:
    • overshoot :超出边界时弹簧会继续弹动。
    • bounceStart :当拖拽到开始位置时弹簧会弹动。
    • bounceEnd :当拖拽到结束位置时弹簧会弹动。
    • bounceBoth :当拖拽到开始或结束位置时弹簧会弹动。
  • rotationCenterId :定义旋转中心的视图 ID。
  • touchRegionId :定义触摸区域的视图 ID。
  • limitBoundsTo :定义限制边界的视图 ID。
  • nestedScrollFlags :定义嵌套滚动的标志位,可以有以下几种取值:
    • none :不支持嵌套滚动。
    • disablePostScroll :禁止滚动结束后的滚动。
    • disableScroll :禁止滚动。
    • supportScrollUp :支持向上滚动。
  • moveWhenScrollAtTop :定义是否在滚动到顶部时允许拖拽。
6. KeyFrameSet

用来描述一系列运动过程中的关键帧。可以利用它使动画效果变的更复杂。其子元素包含KeyPosition、KeyAttribute、KeyCycle、KeyTimeCycle、KeyTrigger。

6.1. KeyPosition

指定动画序列中特定时刻的位置(中间状态的位置),用于调整默认的运动路径。

  • motionTarget :定义应用此关键帧的运动目标,可以是一个视图或者一个运动场景。

  • framePosition :定义关键帧在动画中的位置。关键帧的位置取值为0 到 100 之间的整数,这个值相当于动画过程(时间)的百分比。(什么时候关键帧起作用)。

  • percentX、percentY :定义关键帧在 X 和 Y 轴上的位置。表示相对参考系的横向和纵向的比例。可以设置为 0 到 1 之间的浮点数。这两个数值的具体意义和keyPositionType 属性的设定有关。

  • keyPositionType :坐标系类型,可以取值为:

    • parentRelative 表示以MotionLayout布局为参考系,布局左上角为(0,0),右下角为(1,1)。例如:
    xml 复制代码
    <KeyFrameSet>
        <KeyPosition
            motion:keyPositionType="parentRelative"
            motion:percentX="0.5"
            motion:percentY="0.2" />
    </KeyFrameSet>

    motion:percentX="0.5",motion:percentY="0.2"就是下图中(0.5,0.2)的位置。

    • deltaRelative 表示以View的起始点作为坐标原点(0,0),结束点作为(1,1)。
    xml 复制代码
     <KeyFrameSet>
        <KeyPosition
            motion:keyPositionType="deltaRelative"
            motion:percentX="0.5"
            motion:percentY="0.2" />
    </KeyFrameSet>

    motion:percentX="0.5",motion:percentY="0.2"就是下图中(0.5,0.2)的位置。

    • pathRelative 表示以View的起始点作为坐标起点,起始点(0,0)与结束点(1,0)之间的连线作为x轴。 x轴顺时针旋转90°作为y轴,等长距离作为刻度。
    xml 复制代码
     <KeyFrameSet>
        <KeyPosition
            motion:keyPositionType="pathRelative"
            motion:percentX="0.5"
            motion:percentY="0.2" />
    </KeyFrameSet>

    motion:percentX="0.5",motion:percentY="0.2"就是下图中(0.5,0.2)的位置。

  • percentWidth、percentHeight :定义宽度和高度的变化量。可以设置为 0 到 1 之间的浮点数,表示从开始状态到结束状态之间的相对变化量。注意,如果宽度或高度没有变化,则这些属性将没有任何效果。

    以下代码代表动画开始时View的宽高为 200px() (percentWidth = 0, percentHeight = 0),动画结束时的宽高为 600px(percentWidth = 1, percentHeight = 1),当framePosition = 50 时,view位于坐标系中(0.5,0.2)的位置,宽度变为 0.8,高度变为0.8,相当于此时view的宽高为 600px x 0.8。

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="3000">
            <KeyFrameSet>
                <KeyPosition
                    motion:framePosition="50"
                    motion:keyPositionType="pathRelative"
                    motion:motionTarget="@id/view_test"
                    motion:percentX="0.5"
                    motion:percentY="0.2"
                    motion:percentWidth="0.8"
                    motion:percentHeight="0.8"/>
            </KeyFrameSet>
            <OnClick
                motion:clickAction="toggle"
                motion:targetId="@id/view_test" />
        </Transition>

        <ConstraintSet android:id="@+id/start">
            <Constraint
                android:id="@id/view_test"
                android:layout_width="200px"
                android:layout_height="200px"
                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/view_test"
                android:layout_width="600px"
                android:layout_height="600px"
                motion:layout_constraintEnd_toEndOf="parent"
                motion:layout_constraintTop_toTopOf="parent" />
        </ConstraintSet>
    </MotionScene>
  • transitionEasing :定义关键帧的过渡缓动效果。可以使用 Android 系统中提供的各种缓动函数,比如 standard, accelerate、decelerate、linear等。
  • pathMotionArc :定义关键帧在路径上的运动方式。可以设置为 none、startVertical、startHorizontal、flip之一。
  • curveFit :定义关键帧的插值方式。可以设置为 linear或spline。
  • sizePercent :定义宽度和高度的百分比。可以设置为 0 到 1 之间的浮点数,表示相对于视图父级的百分比。
6.2. 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 :定义视图的位置偏移量。

如设置动画到一半时透明度为0.2,缩放为原控件的0.2倍:

xml 复制代码
    <KeyFrameSet>
        <KeyAttribute
            motion:framePosition="50"
            motion:motionTarget="@id/view_test"
            android:alpha="0.2"
            android:scaleX="0.2"
            android:scaleY="0.2" />
    </KeyFrameSet>
6.3. KeyCycle

根据给定的函数对设定的属性进行周期性变化。

  • motionTarget :想要控制的控件id。
  • wavePeriod :表示运动的周期数,
  • waveShape :表示周期的函数,这里支持的函数有sin,cos,square,triangle,sawtooth,reverseSawtooth和bounce 动画会根据上面的wavePeriod,waveShape对如下支持的属性进行周期变化
    • alpha
    • elevation
    • rotation
    • rotationX
    • rotationY
    • scaleX
    • scaleY
    • translationX
    • translationY
    • translationZ
6.4. KeyTimeCycle

KeyTimeCycle 可以在关键帧上按照一些周期函数,周期性的改变其属性值。 KeyTimeCycle 是在帧上做周期性,KeyCycle 是在动画过程中做周期性。

6.5. KeyTrigger

在动画中调用控件的指定方法。

  • motionTarget :想要控制的控件id
  • framePosition :取值范围和意义与在KeyPosition元素中相同,当动画执行到framePosition设定的位置时会执行onCross,onPositiveCross,onNegativeCros指定的方法。
  • onCross :指定需要调用的方法名,控件中必须有和此属性指定方法名同名的方法。无论动画正向还是反相只要当动画执行到framePosition设置的位置都会执行指定方法。
  • onPositiveCross :作用同onCross,但只有正向执行动画到达framePosition 设置的位置时才会执行指定的方法。
  • onNegativeCross :作用同onCross,但只有反向执行动画到达framePosition 设置的位置时才会执行指定的方法。 如在AppCompatToggleButton中添加toggle方法用来控制开关。
java 复制代码
public class CustomButton extends AppCompatToggleButton {
    
    ......

    /**
     * 添加的方法
     */
    public void toggle() {
        setChecked(!isChecked());
    }
}

MotionScene :

xml 复制代码
    <KeyFrameSet>
        <KeyTrigger
            motion:framePosition="50"
            motion:motionTarget="@id/view_btn"
            motion:onCross="toggle" />
    </KeyFrameSet>

效果图: 开关由关闭状态变为开启状态

7. ConstraintSet(类似于Constrainlayout)

用来设置视图在开始或者结束时各个控件的位置和大小等状态。只有一个id标签,可以有多个Constraint元素。

  • id :唯一标识符(start/end)
7.1 Constraint

每一个Constraint元素对应一个id属性所指向的View。 Constraint元素中我们可以设置控件的大小并使用ConstraintLayout的属性来设置控件位置。还可以插入以下属性: - alpha - visibility - elevation - rotationrotationXrotationY - translationXtranslationYtranslationZ - scaleXscaleY

7.1.1 CustomAttribute

包含在Constraint元素中,一个 本身包含两个属性:

  • attributeName :必需属性,与控件中具有 getter 和 setter 方法的属性相对应。 比如填写motion:attributeName = "backgroundColor"那么我们的控件中就必须有基本的 getBackgroundColor()setBackgroundColor() 方法。
  • 第二个属性需要基于上面填写的属性来决定。 比如上面填写的backgroundColor这里我们就需要使用customColorValue。以下是支持的数据类型:
  • customColorValue 适用于颜色
  • customColorDrawableValue 适用于颜色的drawable
  • customPixelDimension 适用于像素
  • customIntegerValue 适用于整数
  • customFloatValue 适用于浮点值
  • customStringValue 适用于字符串
  • customDimension 适用于尺寸
  • customBoolean 适用于布尔值

指定自定义属性时,必须在开始和结束的 ConstraintSet 元素中都为其指定。如下代码所示:

xml 复制代码
    <ConstraintSet android:id="@+id/start">
        <Constraint
            ......
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="@color/viewColor" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            ......
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="@color/transformColor" />
        </Constraint>
    </ConstraintSet>

三、实现开头动画的效果

1. 顶部大图及背景

效果图如下:

1.1 首先在布局文件中添加一个ImageView来显示图片,添加一个等大小的View作为背景。
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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/view_fullscreen_scene">

    <View
        android:id="@+id/view_top"
        android:layout_width="match_parent"
        android:layout_height="360px"
        android:background="@color/black" />

    <ImageView
        android:id="@+id/iv_top"
        android:layout_width="0px"
        android:layout_height="0px"
        android:scaleType="centerCrop"
        android:src="@mipmap/img" />

</androidx.constraintlayout.motion.widget.MotionLayout>
1.2 接下来为图片ImageView和背景View在MotionScene中添加动画,首先设置图片和背景的开始状态。
xml 复制代码
<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/view_top"
        android:layout_width="match_parent"
        android:layout_height="360px"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintTop_toTopOf="parent" />
    <Constraint
        android:id="@+id/iv_top"
        android:layout_width="match_parent"
        android:layout_height="0px"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toEndOf="@id/view_top"
        motion:layout_constraintStart_toStartOf="@id/view_top"
        motion:layout_constraintTop_toTopOf="@+id/view_top" />
</ConstraintSet>
1.3 然后设置图片和背景的结束状态。
xml 复制代码
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/view_top"
        android:layout_width="match_parent"
        android:layout_height="120px"
        motion:layout_constraintBottom_toTopOf="@+id/nav"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintStart_toStartOf="parent" />
    <Constraint
        android:id="@+id/iv_top"
        android:layout_width="0px"
        android:layout_height="0px"
        android:layout_marginTop="10px"
        android:layout_marginBottom="10px"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintDimensionRatio="W, 4:3"
        motion:layout_constraintStart_toStartOf="@id/view_top"
        motion:layout_constraintTop_toTopOf="@+id/view_top" />
</ConstraintSet>

ConstraintSet标签用来设置界面一种状态下的布局(ConstraintLayout) Constraint标签用来描述控件的位置和属性等。 这里设置ImageView和View的开始是宽度为match_parent,高度为360px,结束时宽度不变,高度为120px。并设置ImageView结束时的尺寸比为 4 :3

需要在开始和结束的两个Constraint中为控件设置大小,即使控件大小没有改变也需要在两边都设置好大小。

1.4 然后设置开始和结束状态,动画执行时间。
xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
</Transition>
1.5 然后对上方View添加手势响应动作。在Transition标签中添加OnSwipe标签即可。
xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragDown"
        motion:touchAnchorId="@+id/view_top"
        motion:touchAnchorSide="bottom" />
</Transition>

OnSwipe表示拖动执行动画。motion:dragDirection="dragDown"表示向下边拖动执行动画。

1.6 完善ImageView的动画

动画执行到85的进度时,保持宽度及x位置不变。

xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragDown"
        motion:touchAnchorId="@+id/view_top"
        motion:touchAnchorSide="bottom" />
    <KeyFrameSet>
        <KeyPosition
            motion:framePosition="85"
            motion:motionTarget="@id/iv_top"
            motion:percentWidth="0"
            motion:percentX="0" />
    </KeyFrameSet>
</Transition>
2. 三个按钮

效果图

按钮动画较为简单,平移+渐变。

2.1 开始状态
xml 复制代码
<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/iv_previous"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="100px"
        android:alpha="0"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toStartOf="@id/iv_pause"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
    <Constraint
        android:id="@+id/iv_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="100px"
        android:alpha="0"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toStartOf="@id/iv_next"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
    <Constraint
        android:id="@+id/iv_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50px"
        android:alpha="0"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toEndOf="@id/view_top"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
</ConstraintSet>
2.2 结束状态
xml 复制代码
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/iv_previous"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="100px"
        android:alpha="1"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toStartOf="@id/iv_pause"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
    <Constraint
        android:id="@+id/iv_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="100px"
        android:alpha="1"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toStartOf="@id/iv_next"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
    <Constraint
        android:id="@+id/iv_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="50px"
        android:alpha="1"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintEnd_toEndOf="@id/view_top"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
</ConstraintSet>
2.3 完善动画效果

动画执行到85的进度时,透明度变为0.1。

xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragDown"
        motion:touchAnchorId="@+id/view_top"
        motion:touchAnchorSide="bottom" />
    <KeyFrameSet>
        <KeyAttribute
            android:alpha="0.10"
            motion:framePosition="85"
            motion:motionTarget="@id/iv_previous" />
        <KeyAttribute
            android:alpha="0.10"
            motion:framePosition="85"
            motion:motionTarget="@id/iv_pause" />
        <KeyAttribute
            android:alpha="0.10"
            motion:framePosition="85"
            motion:motionTarget="@id/iv_next" />
    </KeyFrameSet>
</Transition>
3. Test文字

效果图:

3.1 开始状态
xml 复制代码
<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:alpha="0"
        motion:layout_constraintBottom_toBottomOf="@id/view_top"
        motion:layout_constraintStart_toEndOf="@id/view_top"
        motion:layout_constraintTop_toTopOf="@id/view_top" />
</ConstraintSet>
3.2 结束状态
xml 复制代码
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="30px"
        android:alpha="1"
        motion:layout_constraintBottom_toBottomOf="@+id/view_top"
        motion:layout_constraintStart_toEndOf="@+id/iv_top"
        motion:layout_constraintTop_toTopOf="@+id/view_top" />
</ConstraintSet>
3.3 完善文字动画效果

动画执行到85的进度时,透明度为0.1。

xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragDown"
        motion:touchAnchorId="@+id/view_top"
        motion:touchAnchorSide="bottom" />
    <KeyFrameSet>
        <KeyAttribute
            android:alpha="0.10"
            motion:framePosition="85"
            motion:motionTarget="@id/tv_text" />
    </KeyFrameSet>
</Transition>
4. 上方圆形图片

效果图:

4.1 开始状态
xml 复制代码
<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/iv_round"
        android:layout_width="0px"
        android:layout_height="0px"
        android:alpha="0"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
4.2 结束状态
xml 复制代码
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/iv_round"
        android:layout_width="450px"
        android:layout_height="450px"
        android:alpha="1"
        motion:layout_constraintBottom_toTopOf="@id/view_top"
        motion:layout_constraintEnd_toEndOf="parent"
        motion:layout_constraintStart_toStartOf="parent"
        motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
4.3 完善圆形图片效果

动画执行到50的进度时,透明度为0。

xml 复制代码
<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@id/start"
    motion:duration="1000">
    <OnSwipe
        motion:dragDirection="dragDown"
        motion:touchAnchorId="@+id/view_top"
        motion:touchAnchorSide="bottom" />
    <KeyFrameSet>
        <KeyAttribute
            android:alpha="0"
            motion:framePosition="50"
            motion:motionTarget="@id/iv_round" />
    </KeyFrameSet>
</Transition>
5. 下方导航栏

屏幕外-->屏幕底部,就不放图了。

5.1 开始状态
xml 复制代码
<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            motion:layout_constraintTop_toBottomOf="parent" />
</ConstraintSet>
5.2 结束状态
xml 复制代码
<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        motion:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>

代码整合之后文章开头的动画效果就实现了。

到这里一些基本动画效果及属性就介绍完了。

代码地址

Thanks。

相关推荐
太空漫步112 小时前
android社畜模拟器
android
海绵宝宝_5 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
凯文的内存6 小时前
android 定制mtp连接外设的设备名称
android·media·mtp·mtpserver
天若子6 小时前
Android今日头条的屏幕适配方案
android
林的快手8 小时前
伪类选择器
android·前端·css·chrome·ajax·html·json
望佑8 小时前
Tmp detached view should be removed from RecyclerView before it can be recycled
android
xvch10 小时前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
人民的石头14 小时前
Android系统开发 给system/app传包报错
android
yujunlong391914 小时前
android,flutter 混合开发,通信,传参
android·flutter·混合开发·enginegroup
rkmhr_sef15 小时前
万字详解 MySQL MGR 高可用集群搭建
android·mysql·adb