前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android-MotionLayout动画

Android-MotionLayout动画

作者头像
android_薛之涛
发布2021-12-08 13:40:41
9720
发布2021-12-08 13:40:41
举报
文章被收录于专栏:Android-薛之涛Android-薛之涛
参考资料

https://mp.weixin.qq.com/s/8DhoUK9YlbRGwr6ALp2CBw 话不多说,上图为敬:

motionlayout.gif

效果图分析
  • 头部用户信息区域的渐隐渐显
  • 头部用户信息区域的位置变化
  • 控件大小的变化(比如关注按钮)
  • 文字大小及颜色的变化(比如用户名称)
添加依赖

MotionLayout要求ConstraintLayout的版本在2.0.0及其以上.依赖如下: implementation 'androidx.constraintlayout:constraintlayout:2.0.0'

创建布局

创建一个名为activity_main.xml的布局文件,根布局为ConstraintLayout,然后选择Design->Component Tree -> 选中根布局ConstratintLayout右键,选择Convert to MotionLayout,将其根布局转为MotionLayout。然后Design面板变成了如下:多了动画预览窗口.

image.png

注意:我们尽量采用右键自动转化为MotionLayout的方式,避免手动将ConstratintLayout变为MotionLayout根布局文件,有时不能正常显示的问题,可能需要重启。

创建MotionScene动画资源文件

我们返回去看一眼根布局,已经变成了MotionLayout,而且layoutDescription属性指向了自动为我们创建的MotionScene动画资源文件.

image.png

我们紧接着看一眼activity_main_scene这个文件,该文件位于res-xml文件夹下的activity_main_scene.xml.

代码语言:javascript
复制
<?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文件的基本结构说明如下:

  • MotionScene为项目的根标签
  • Transition指定了动画要使用的ConstraintSet,及动画的触发方式等
  • ConstraintSet指定了动画开始页面和结束页面的控件状态
  • KeyFrameSet 用来描述一系列运动过程中的关键,我们稍后说
完善布局
添加背景动画

由于MotionLayout是ConstraintLayout的子类,所以我们可以像使用ConstraintLayout一样使用它.我们先来将背景添加上,代码如下: activity_main.xml中:

代码语言:javascript
复制
    <ImageView
        android:id="@+id/wallbg"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:src="@mipmap/bg"
        android:scaleType="centerCrop"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

activity_main_scene.xml中:

代码语言:javascript
复制
 <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@mipmap/bg"
            android:scaleType="centerCrop"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"/>

    </ConstraintSet>

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

        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="0dp"
            android:layout_height="240dp"
            android:src="@mipmap/bg"
            android:scaleType="centerCrop"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
           />
    </ConstraintSet>

id为start的Constraint定义了动画开始的状态;id为end的Constraint的则定义了动画结束的状态,Constraint标签用来描述一个控件的位置和属性,但光有这些还不够,我们还需要添加一个动画的触发方式,这里有两种触发方式:

  • <OnClick>标签表示点击触发动画
  • <OnSwipe>标签表示拖拽执行动画 这里我们选择后者:<OnSwipe>标签要放在Transition标签中,代码如下:
代码语言:javascript
复制
    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
       <KeyFrameSet>
       </KeyFrameSet>

        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@+id/wallbg"
            motion:touchAnchorSide="bottom"
            >
        </OnSwipe>
    </Transition>

解释下相关的属性

  • dragDirection 拖拽的方向
  • touchAnchorId 滑动影响的控件id
  • touchAnchorSide 滑动所固定到的目标视图的一侧,可以配合dragDirection理解,二者相反

在xml布局文件和motionscene的文件中,控件的id不能少,Constraint标签中layout_打头的属性都要有,其余可以省略比如src属性,因为在xml中已经赋值了

我们现在看一下效果,可以在design面板中先预览一下:

image.png

点击1所指的start可以预览start状态,点击2所指的end预览end状态。点击上方3所指的连线,可以在下方面板点击播放键查看动画,当然也可以自己拖拽查看。

image.png

我们直接运行看效果吧:

image.gif

添加右下方收藏按钮等动画

activity_main.xml代码:

代码语言:javascript
复制
   <Constraint
            android:id="@+id/iv_collection"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toStartOf="@id/iv_share" />
        <Constraint
            android:id="@+id/iv_share"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toStartOf="@id/iv_more"/>
        <Constraint
            android:id="@+id/iv_more"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"/>

activity_main_scene.xml代码:

代码语言:javascript
复制
  <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@mipmap/bg"
            android:scaleType="centerCrop"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"/>
        <Constraint
            android:id="@+id/iv_collection"
            android:layout_width="32dp"
            android:layout_height="32dp"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent" />
        <Constraint
            android:id="@+id/iv_share"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="25dp"
            motion:layout_constraintTop_toBottomOf="@id/iv_collection"
            motion:layout_constraintEnd_toEndOf="parent"/>
        <Constraint
            android:id="@+id/iv_more"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="25dp"
            motion:layout_constraintTop_toBottomOf="@id/iv_share"
            motion:layout_constraintEnd_toEndOf="parent"/>

    </ConstraintSet>

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

        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="0dp"
            android:layout_height="240dp"
            android:src="@mipmap/bg"
            android:scaleType="centerCrop"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
           />

        <Constraint
            android:id="@+id/iv_collection"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toStartOf="@id/iv_share" />
        <Constraint
            android:id="@+id/iv_share"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toStartOf="@id/iv_more"/>
        <Constraint
            android:id="@+id/iv_more"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"/>

    </ConstraintSet>

在motionlayout根布局中添加app:showPaths="true"可以在手机上看到动画的移动轨迹,我们加入一下

运行看效果:

image2.gif

但是我们看这个收藏按钮的运动轨迹有点单调,就是直线从A点到B点.我们来改进一下,这就需要用到我们上面提到的 KeyFrameSet了,KeyFrameSet包含于Transition标签中,这个标签用来描述一系列运动过程中的关键帧。我们可以利用其使动画效果变的更复杂。其子元素包含KeyPosition、KeyAttribute等,我们先使用一下其子元素KeyPosition(因为要改变的是运动轨迹),具体的用法如下:

activity_main_scene.xml代码:

代码语言:javascript
复制
     <KeyFrameSet>
           <KeyPosition
               motion:motionTarget="@+id/iv_collection"
               motion:framePosition="50"
               motion:keyPositionType="deltaRelative"
               motion:percentX="0.7"
               motion:percentY="0.5"
               >
           </KeyPosition>
           <KeyPosition
               motion:motionTarget="@+id/iv_share"
               motion:framePosition="50"
               motion:keyPositionType="deltaRelative"
               motion:percentX="0.7"
               motion:percentY="0.5"
               >
           </KeyPosition>
           <KeyPosition
               motion:framePosition="50"
               motion:keyPositionType="deltaRelative"
               motion:motionTarget="@+id/iv_more"
               motion:percentX="0.7"
               motion:percentY="0.5" >
           </KeyPosition>
       </KeyFrameSet>

运行效果如下:

image3.gif

通过设置app:showPaths="true"我们可以很明显的看到运动轨迹发生了变化. 关键属性说明如下:

  • motionTarget 受影响的控件id
  • framePosition 关键帧的位置取值为1 到 99 之间的整数。这里取值50就是指动画进行到一半的位置
  • percentX和 percentY 控件到达framePosition点时的位置,是个float值。这两个属性的具体意义需要根据keyPositionType的类型来定
  • keyPositionType 有多种取值,以我们代码中为例motion:keyPositionType="deltaRelative",取值为deltaRelative时:percentX 和 percentY 坐标系以constraintSetStart指定的位置为原点,X轴平行于父布局X轴,方向为动画开始的x点指向结束点x点,其值0为原点,1为动画整个动画X轴方向的运动距离。Y轴平行于父布局Y轴,方向为动画开始的y点指向结束点y点,其值0为原点,1为动画整个动画Y轴方向的运动距离。如下:

image.png

关注按钮

注意:关注按钮的控件大小和字体大小的变化,运动过程中也伴随着渐变效果.这样的效果我们就需要用的KeyFrameSet中的另一个子元素KeyAttribute以及Constraint 中的CustomAttribute标签配合完成.

activity_main.xml相关代码如下:

代码语言:javascript
复制
 <Button
        android:id="@+id/btn_attention"
        android:layout_width="110dp"
        android:layout_height="50dp"
        android:textSize="18sp"
        android:text="关注我 +"
        app:layout_constraintHorizontal_bias="0.8"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

activity_main_scene.xml相关代码如下:

代码语言:javascript
复制
<!-- 设置关注按钮不同帧渐变-->
<!-- 用到了两个KeyAttribute每个控件使用了两个,是因为要实现在动画的中间部分保持0.0的透明度不变,在快要结束时再变得可见。-->
           <KeyAttribute
               motion:motionTarget="@+id/btn_attention"
               motion:framePosition="20"
               android:alpha="0.0">
          </KeyAttribute>
           <KeyAttribute
               motion:motionTarget="@+id/btn_attention"
               motion:framePosition="80"
               android:alpha="0.0">
           </KeyAttribute>

在ConstraintSet的start状态

代码语言:javascript
复制
        <Constraint
            android:id="@+id/btn_attention"
            android:layout_width="110dp"
            android:layout_height="50dp"
            motion:layout_constraintHorizontal_bias="0.8"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="18"/>
            <CustomAttribute
                motion:attributeName="textColor"
                motion:customColorValue="@color/black"/>

        </Constraint>

在ConstraintSet的end状态

代码语言:javascript
复制
       <Constraint
            android:id="@+id/btn_attention"
            android:layout_width="90dp"
            android:layout_height="40dp"
            android:layout_marginTop="240dp"
            motion:layout_constraintHorizontal_bias="0.6"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="13"/>
            <CustomAttribute
                motion:attributeName="textColor"
                motion:customColorValue="@color/white"/>

        </Constraint>

效果如下:

image4

相关属性说明: 关于Constraint Constraint:每一个Constraint元素对应一个id属性所指向的View,我们必须为控件设置宽和高即使在布局xml中已经设置过了.

  • id :用来指定布局中对应的view
  • CustomAttribute: 包含在Constraint元素中,一个 <CustomAttribute> 本身包含两个属性 1.motion:attributeName 是必需属性,并且必须与控件中具有 getter 和 setter 方法的属性相对应。 2.第二个属性我们需要基于上面填写的属性来决定。比如上面填写的backgroundColor这里我们就需要使用customColorValue。

关于KeyAttribute 指定动画序列中特定时刻的视图属性。 motionTarget 和framePosition 与KeyPosition意义相同 KeyAttribute还支持visibility、rotation、scale等控件基本属性。

最后附上所有代码 activity_main.xml

代码语言:javascript
复制
<?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"
    app:layoutDescription="@xml/activity_third_scene"
    tools:context=".ThirdActivity">

    <!--    app:showPaths="true"-->
    <!--背景图片-->

    <!--    用户信息区域-->
    <ImageView
        android:id="@+id/wallbg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@mipmap/bg"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv_avatar"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/avatar"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_userName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="15dp"
        android:text="Android-薛之涛"
        android:textColor="@color/purple_500"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
        app:layout_constraintStart_toEndOf="@id/iv_avatar"
        app:layout_constraintTop_toTopOf="@id/iv_avatar" />


    <Button
        android:id="@+id/btn_attention"
        android:layout_width="90dp"
        android:layout_height="50dp"
        android:layout_marginStart="25dp"
        android:text="关注 +"
        android:textColor="@color/white"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
        app:layout_constraintStart_toEndOf="@id/tv_userName"
        app:layout_constraintTop_toTopOf="@id/iv_avatar" />

    <!--    java.lang.RuntimeException: All children of ConstraintLayout must have ids to use ConstraintSet-->
    <ImageView
        android:id="@+id/iv_more"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginEnd="10dp"
        android:src="@mipmap/more"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv_share"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginTop="30dp"
        android:layout_marginEnd="10dp"
        android:src="@mipmap/share"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_more" />

    <ImageView
        android:id="@+id/iv_collection"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginTop="30dp"
        android:layout_marginEnd="10dp"
        android:src="@mipmap/collection"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_share" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/listview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="320dp"
        android:padding="15dp"
        android:visibility="gone"
        app:layout_constraintBottom_toTopOf="@id/ed_message"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/tv_evaluationName1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="张三说:"
            android:textColor="@color/purple_500"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_evaluationMsg1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            android:text="背景的美女好漂亮"
            app:layout_constraintBottom_toBottomOf="@id/tv_evaluationName1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/tv_evaluationName1"
            app:layout_constraintTop_toTopOf="@id/tv_evaluationName1" />

        <TextView
            android:id="@+id/tv_evaluationName2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="李四说:"
            android:textColor="@color/purple_500"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_evaluationName1" />

        <TextView
            android:id="@+id/tv_evaluationMsg2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            android:text="背景的美女好漂亮"
            app:layout_constraintBottom_toBottomOf="@id/tv_evaluationName2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@id/tv_evaluationName2"
            app:layout_constraintTop_toTopOf="@id/tv_evaluationName2" />


    </androidx.constraintlayout.widget.ConstraintLayout>

    <EditText
        android:id="@+id/ed_message"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:hint="请说点什么吧"
        android:textColor="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
```
**activity_main_scene.xml**
```
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
        <KeyFrameSet>
            <!--           KeyFrameSet 这个标签用来描述一系列运动过程中的关键帧-->
            <!--            KeyPosition用来指定动画序列中特定时刻的位置-->
            <!--            motion:motionTarget表示受影响的控件id-->
            <!--            motion:framePosition 取值为1 到 99 之间的整数。这里取值50就是指动画进行到一半的位置 -->
            <!--            motion:percentX和motion:percentY是控件到达motion:framePosition点时的位置,是个float值。-->
            <!--            这两个属性的具体意义需要根据motion:keyPositionType的类型来定-->

            <!--            给收藏和分享调整运动轨迹-->
            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_collection"
                motion:percentX="0.7"
                motion:percentY="0.5" />

            <KeyPosition
                motion:framePosition="50"
                motion:keyPositionType="deltaRelative"
                motion:motionTarget="@+id/iv_share"
                motion:percentX="0.7"
                motion:percentY="0.5" />

            <!--          给头像和名字设置渐变效果-->
            <!--            动画的中间部分保持0.2的透明度不变,在快要结束时再变得可见-->
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="30"
                motion:motionTarget="@+id/iv_avatar" />
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="30"
                motion:motionTarget="@+id/tv_userName" />
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="80"
                motion:motionTarget="@+id/iv_avatar" />
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="80"
                motion:motionTarget="@+id/tv_userName" />


            <!--            给关注按钮调整效果-->
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="20"
                motion:motionTarget="@+id/btn_attention" />
            <KeyAttribute
                android:alpha="0.2"
                motion:framePosition="80"
                motion:motionTarget="@+id/btn_attention" />


        </KeyFrameSet>
        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@id/wallbg"
            motion:touchAnchorSide="bottom" />
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@mipmap/bg"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.0"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintVertical_bias="0.0" />
        <!--        注意:Constraint里的属性可以不用写已经在xml中配置过的非layout开头的,除了id,
                    而layout_开头的属性可以直接写值-->
        <Constraint
            android:id="@+id/iv_avatar"
            android:layout_width="60dp"
            android:layout_height="60dp"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@+id/tv_userName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            motion:layout_constraintBottom_toBottomOf="@id/iv_avatar"
            motion:layout_constraintStart_toEndOf="@id/iv_avatar"
            motion:layout_constraintTop_toTopOf="@id/iv_avatar">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="18" />
            <CustomAttribute
                motion:attributeName="textColor"
                motion:customColorValue="@color/purple_500" />
        </Constraint>
        <Constraint
            android:id="@+id/btn_attention"
            android:layout_width="90dp"
            android:layout_height="50dp"
            android:layout_marginStart="25dp"
            motion:layout_constraintBottom_toBottomOf="@id/iv_avatar"
            motion:layout_constraintStart_toEndOf="@id/tv_userName"
            motion:layout_constraintTop_toTopOf="@id/iv_avatar">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="18" />
        </Constraint>
        <Constraint
            android:id="@+id/iv_collection"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="30dp"
            android:layout_marginEnd="10dp"
            android:src="@mipmap/collection"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/iv_share"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="30dp"
            android:layout_marginEnd="10dp"
            android:src="@mipmap/share"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/iv_collection" />
        <Constraint
            android:id="@+id/iv_more"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="30dp"
            android:layout_marginEnd="10dp"
            android:src="@mipmap/more"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/iv_share" />

        <Constraint
            android:id="@+id/ed_message"
            android:layout_width="0dp"
            android:layout_height="60dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent" />

        <Constraint
            android:id="@+id/listview"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="320dp"
            android:visibility="gone"
            motion:layout_constraintBottom_toTopOf="@id/ed_message"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <!--        -->
            <!--            <CustomAttribute-->
            <!--                motion:attributeName="visibility"-->
            <!--                motion:customStringValue="gone"/>-->
        </Constraint>
        <Constraint
            android:id="@+id/tv_evaluationName1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/tv_evaluationMsg1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            motion:layout_constraintBottom_toBottomOf="@id/tv_evaluationName1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toEndOf="@id/tv_evaluationName1"
            motion:layout_constraintTop_toTopOf="@id/tv_evaluationName1" />
        <Constraint
            android:id="@+id/tv_evaluationName2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/tv_evaluationName1" />
        <Constraint
            android:id="@+id/tv_evaluationMsg2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            motion:layout_constraintBottom_toBottomOf="@id/tv_evaluationName2"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toEndOf="@id/tv_evaluationName2"
            motion:layout_constraintTop_toTopOf="@id/tv_evaluationName2" />


    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/wallbg"
            android:layout_width="match_parent"
            android:layout_height="220dp"
            android:scaleType="centerCrop"
            android:src="@mipmap/bg"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/iv_avatar"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginTop="240dp"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@+id/tv_userName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"
            motion:layout_constraintBottom_toBottomOf="@id/iv_avatar"
            motion:layout_constraintStart_toEndOf="@id/iv_avatar"
            motion:layout_constraintTop_toTopOf="@id/iv_avatar">

            <!--            控件中必须具有 getter 和 setter 方法的属性相对应-->
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="14" />
            <CustomAttribute
                motion:attributeName="textColor"
                motion:customColorValue="@color/black" />
        </Constraint>
        <Constraint
            android:id="@+id/btn_attention"
            android:layout_width="80dp"
            android:layout_height="40dp"
            android:layout_marginEnd="25dp"
            motion:layout_constraintBottom_toBottomOf="@id/iv_avatar"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="@id/iv_avatar">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customFloatValue="14" />
        </Constraint>

        <Constraint
            android:id="@+id/iv_more"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="30dp"
            android:src="@mipmap/more"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent" />

        <Constraint
            android:id="@+id/iv_share"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="30dp"
            android:src="@mipmap/share"
            motion:layout_constraintBottom_toBottomOf="@id/iv_more"
            motion:layout_constraintEnd_toStartOf="@id/iv_more"
            motion:layout_constraintTop_toTopOf="@id/iv_more" />

        <Constraint
            android:id="@+id/iv_collection"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginEnd="30dp"
            android:src="@mipmap/collection"
            motion:layout_constraintBottom_toBottomOf="@id/iv_share"
            motion:layout_constraintEnd_toStartOf="@id/iv_share"
            motion:layout_constraintTop_toTopOf="@id/iv_share" />

        <Constraint
            android:id="@+id/ed_message"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_marginEnd="60dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toStartOf="@id/iv_share"
            motion:layout_constraintStart_toStartOf="parent" />
        <Constraint
            android:id="@+id/listview"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="320dp"
            android:visibility="visible"
            motion:layout_constraintBottom_toTopOf="@id/ed_message"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <!--            <CustomAttribute-->
            <!--                motion:attributeName="visibility"-->
            <!--                motion:customStringValue="visible"-->
            <!--                />-->
        </Constraint>
        <Constraint
            android:id="@+id/tv_evaluationName1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/tv_evaluationMsg1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            motion:layout_constraintBottom_toBottomOf="@id/tv_evaluationName1"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toEndOf="@id/tv_evaluationName1"
            motion:layout_constraintTop_toTopOf="@id/tv_evaluationName1" />
        <Constraint
            android:id="@+id/tv_evaluationName2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/tv_evaluationName1" />
        <Constraint
            android:id="@+id/tv_evaluationMsg2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="15dp"
            motion:layout_constraintBottom_toBottomOf="@id/tv_evaluationName2"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toEndOf="@id/tv_evaluationName2"
            motion:layout_constraintTop_toTopOf="@id/tv_evaluationName2" />
    </ConstraintSet>
</MotionScene>
```


ok,关于MotionLayout就说这么多,更详细的内容推荐大家去查看官方文档或者其它资料.
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/11/3 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考资料
  • 效果图分析
  • 添加依赖
  • 创建布局
  • 创建MotionScene动画资源文件
  • 完善布局
    • 添加背景动画
      • 添加右下方收藏按钮等动画
        • 关注按钮
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档