探索 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。

相关推荐
帅得不敢出门9 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了11 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任13 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山13 小时前
Android“引用们”的底层原理
android·java
迃-幵13 小时前
力扣:225 用队列实现栈
android·javascript·leetcode
大风起兮云飞扬丶14 小时前
Android——从相机/相册获取图片
android
Rverdoser14 小时前
Android Studio 多工程公用module引用
android·ide·android studio
aaajj14 小时前
[Android]从FLAG_SECURE禁止截屏看surface
android
@OuYang14 小时前
android10 蓝牙(二)配对源码解析
android
Liknana14 小时前
Android 网易游戏面经
android·面试