阳光沙滩
让学习编程变得简单
Android MotionLayout 动画 的使用
发表于 2019-12-27    阅读次数 414

先上效果图:

图片描述

MotionLayout 是这俩年出的一个 比较'花哨'的控件,在做一些动画位移效果时特别的好用. 首先导入依赖: implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta2"

第一步: 默认效果:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageView
        android:id="@+id/star1"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/star2"


        app:layout_constraintTop_toTopOf="parent"
        app:src="@drawable/star" />

    <ImageView
        android:id="@+id/star2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toRightOf="@id/star1"
        app:layout_constraintRight_toLeftOf="@id/star3"

        app:layout_constraintTop_toTopOf="parent"
        app:src="@drawable/sun" />

    <ImageView
        android:id="@+id/star3"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star2"
        app:layout_constraintRight_toLeftOf="@id/star4"

        app:layout_constraintTop_toTopOf="parent"
        app:src="@drawable/moon"

        />

    <ImageView
        android:id="@+id/star4"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"

        app:layout_constraintLeft_toRightOf="@id/star3"
        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toTopOf="parent"
        app:src="@drawable/cloud" />



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

图片描述

接着,把上面的代码注释了 写一下动画之后的位置 ,注意:控件的id不变,调整位置

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <ImageView
        android:id="@+id/star1"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/star"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/star2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/sun"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star3"
        app:layout_constraintRight_toLeftOf="@id/star1"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/star3"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/moon"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star4"
        app:layout_constraintRight_toLeftOf="@id/star2"
        app:layout_constraintTop_toTopOf="parent"
        />

    <ImageView
        android:id="@+id/star4"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/cloud"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/star3"
        app:layout_constraintTop_toTopOf="parent" />



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

图片描述

第二步: 在Res下新建一个xml文件夹, 图片描述

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

        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star1"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toLeftOf="@id/star4"
            motion:layout_constraintTop_toTopOf="parent"
            >


        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent">

        </Constraint>


    </ConstraintSet>

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

        <!--1号 去最右边  其他 同理 重新写 不光是 换个  id-->
        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toRightOf="parent"

            motion:layout_constraintTop_toTopOf="parent">
        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toLeftOf="@id/star1"
            motion:layout_constraintTop_toTopOf="parent">
        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star4"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >
        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">


        </Constraint>

    </ConstraintSet>

可以看出 ConstraintSet id start 与 id end 对应上面写的默认效果与动画位移效果 ,只是内部所有的ImageView 变成了Constraint 位置写完了,接下来加他们关联上

<Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="4000">

        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/motion"/>

    </Transition>

这里id/motion 是我们在main.xml里给MotionLayout设置的id,这里表示点击这个id控件时,开始动画,将motionlayout与scene_main关联

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/motion"
    app:layoutDescription="@xml/scene_main"
    tools:context=".MainActivity">


    <ImageView
        android:id="@+id/star1"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/star"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/star2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/sun"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star3"
        app:layout_constraintRight_toLeftOf="@id/star1"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/star3"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/moon"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star4"
        app:layout_constraintRight_toLeftOf="@id/star2"
        app:layout_constraintTop_toTopOf="parent"
        />

    <ImageView
        android:id="@+id/star4"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/cloud"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/star3"
        app:layout_constraintTop_toTopOf="parent" />



</androidx.constraintlayout.motion.widget.MotionLayout>
<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="4000">

        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/motion"/>

    </Transition>

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

        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star1"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toLeftOf="@id/star4"
            motion:layout_constraintTop_toTopOf="parent"
            >


        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent">

        </Constraint>


    </ConstraintSet>

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

        <!--1号 去最右边  其他 同理 重新写 不光是 换个  id-->
        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toRightOf="parent"

            motion:layout_constraintTop_toTopOf="parent">
        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toLeftOf="@id/star1"
            motion:layout_constraintTop_toTopOf="parent">
        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star4"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >
        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">


        </Constraint>

    </ConstraintSet>

</MotionScene>

运行一下 图片描述 加 颜色的变幻 使用 ImageFilterView 这个控件也是与MotionLayout 配套的一个

androidx.constraintlayout.utils.widget.ImageFilterView

将activity_main.xml里的ImageView 替换之后我们在scene_main添加变幻属性

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

        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"

            >
            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>

saturation 是一个颜色变化的属性 这里的attributeName 对应的属性必须是在这个控件里有set get方法 ,点进源码看一下 图片描述 接着变幻的度数是在0-1之间 修改之后的代码:

<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="4000">

        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/motion"/>

    </Transition>

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

        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />
        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star1"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toLeftOf="@id/star4"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>


    </ConstraintSet>

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

        <!--1号 去最右边  其他 同理 重新写 不光是 换个  id-->
        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toRightOf="parent"

            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toLeftOf="@id/star1"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star4"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

    </ConstraintSet>

</MotionScene>

图片描述

第三步: 添加位置起伏

 <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="4000">

        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/motion"/>

        <KeyFrameSet>
            
            <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.25"
                motion:percentY="0" />
            
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.5"
                motion:percentY="1" />

            <KeyPosition
                motion:framePosition="75"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.75"
                motion:percentY="0" />


            <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.75"
                motion:percentY="1" />
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.5"
                motion:percentY="0" />

            <KeyPosition
                motion:framePosition="75"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.25"
                motion:percentY="1" />

            
        </KeyFrameSet>
        
    </Transition>

稍后解释先看效果 图片描述

framePosition 标识 进度 第一个图 移动到 第四个图 总进度是100 我们设置了第一个图的 5个位置 首先 开始位置 和 动画结束位置 是 固定的 也就是framePosition :0 开始位置 framePosition :100 动画结束位置 分析一下这段

  <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.25"
                motion:percentY="0" />

keyPositionType="parentRelative" 表示展开坐标的一种方式 这个比较好理解

图片描述

最后

添加变幻时 的其他动画

 <!--&lt;!&ndash;统一设置 动画&ndash;&gt;-->
            <KeyAttribute
                android:alpha="0.5"
                motion:framePosition="25"
                motion:motionTarget="@id/star1" />
            <KeyAttribute
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star1" />
            <KeyAttribute
                android:rotation="360"
                motion:framePosition="75"
                motion:motionTarget="@id/star1" />

            <KeyAttribute
                android:rotation="360"
                motion:framePosition="25"
                motion:motionTarget="@id/star4" />
            <KeyAttribute
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star4" />
            <KeyAttribute
                android:alpha="0.5"
                motion:framePosition="75"
                motion:motionTarget="@id/star4" />


            <KeyAttribute
                android:alpha="0.5"
                android:rotation="360"
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star2" />


            <KeyAttribute
                android:alpha="0.5"
                android:rotation="360"
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star3" />

意思和上面差不多

布局的高度修改一下 效果:

图片描述 完整代码:

<?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:layout_width="match_parent"
    android:layout_height="200dp"
    android:id="@+id/motion"
    app:layoutDescription="@xml/scene_main"
    tools:context=".MainActivity">


    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/star1"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/star"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/star2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/sun"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star3"
        app:layout_constraintRight_toLeftOf="@id/star1"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/star3"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/moon"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/star4"
        app:layout_constraintRight_toLeftOf="@id/star2"
        app:layout_constraintTop_toTopOf="parent"
        />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/star4"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/cloud"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/star3"
        app:layout_constraintTop_toTopOf="parent" />



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

scene_main.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"
    xmlns:tools="http://schemas.android.com/tools">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="4000">

        <OnClick
            motion:clickAction="toggle"
            motion:targetId="@id/motion"/>

        <KeyFrameSet>

            <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.25"
                motion:percentY="0" />

            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.5"
                motion:percentY="1" />

            <KeyPosition
                motion:framePosition="75"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star1"
                motion:percentX="0.75"
                motion:percentY="0" />


            <KeyPosition
                motion:framePosition="25"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.75"
                motion:percentY="1" />
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.5"
                motion:percentY="0" />

            <KeyPosition
                motion:framePosition="75"
                motion:keyPositionType="parentRelative"
                motion:motionTarget="@id/star4"
                motion:percentX="0.25"
                motion:percentY="1" />

            <!--&lt;!&ndash;统一设置 动画&ndash;&gt;-->
            <KeyAttribute
                android:alpha="0.5"
                motion:framePosition="25"
                motion:motionTarget="@id/star1" />
            <KeyAttribute
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star1" />
            <KeyAttribute
                android:rotation="360"
                motion:framePosition="75"
                motion:motionTarget="@id/star1" />

            <KeyAttribute
                android:rotation="360"
                motion:framePosition="25"
                motion:motionTarget="@id/star4" />
            <KeyAttribute
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star4" />
            <KeyAttribute
                android:alpha="0.5"
                motion:framePosition="75"
                motion:motionTarget="@id/star4" />


            <KeyAttribute
                android:alpha="0.5"
                android:rotation="360"
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star2" />


            <KeyAttribute
                android:alpha="0.5"
                android:rotation="360"
                android:scaleX="1.5"
                android:scaleY="1.5"
                motion:framePosition="50"
                motion:motionTarget="@id/star3" />


        </KeyFrameSet>

    </Transition>

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

        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />
        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star1"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toLeftOf="@id/star4"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="1" />

        </Constraint>


    </ConstraintSet>

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

        <!--1号 去最右边  其他 同理 重新写 不光是 换个  id-->
        <Constraint
            android:id="@+id/star1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/star"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star2"
            motion:layout_constraintRight_toRightOf="parent"

            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/sun"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star3"
            motion:layout_constraintRight_toLeftOf="@id/star1"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/moon"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toRightOf="@id/star4"
            motion:layout_constraintRight_toLeftOf="@id/star2"
            motion:layout_constraintTop_toTopOf="parent"
            >

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

        <Constraint
            android:id="@+id/star4"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/cloud"

            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toLeftOf="@id/star3"
            motion:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                motion:attributeName="saturation"
                motion:customFloatValue="0" />

        </Constraint>

    </ConstraintSet>

</MotionScene>

ok