Android-MotionLayout動畫

參考資料

https://mp.weixin.qq.com/s/8DhoUK9YlbRGwr6ALp2CBw
話不多說,上圖為敬:

motionlayout.gif

效果圖分析

  • 頭部用戶信息區(qū)域的漸隱漸顯
  • 頭部用戶信息區(qū)域的位置變化
  • 控件大小的變化(比如關(guān)注按鈕)
  • 文字大小及顏色的變化(比如用戶名稱)

添加依賴

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

創(chuàng)建布局

創(chuàng)建一個名為activity_main.xml的布局文件囚企,根布局為ConstraintLayout殿托,然后選擇Design->Component Tree -> 選中根布局ConstratintLayout右鍵划提,選擇Convert to MotionLayout片部,將其根布局轉(zhuǎn)為MotionLayout吗浩。然后Design面板變成了如下:多了動畫預(yù)覽窗口.


image.png

注意:我們盡量采用右鍵自動轉(zhuǎn)化為MotionLayout的方式似嗤,避免手動將ConstratintLayout變?yōu)镸otionLayout根布局文件川背,有時不能正常顯示的問題,可能需要重啟。

創(chuàng)建MotionScene動畫資源文件

我們返回去看一眼根布局,已經(jīng)變成了MotionLayout,而且layoutDescription屬性指向了自動為我們創(chuàng)建的MotionScene動畫資源文件.


image.png

我們緊接著看一眼activity_main_scene這個文件,該文件位于res-xml文件夾下的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">

    <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文件的基本結(jié)構(gòu)說明如下:

  • MotionScene為項(xiàng)目的根標(biāo)簽
  • Transition指定了動畫要使用的ConstraintSet,及動畫的觸發(fā)方式等
  • ConstraintSet指定了動畫開始頁面和結(jié)束頁面的控件狀態(tài)
  • KeyFrameSet 用來描述一系列運(yùn)動過程中的關(guān)鍵,我們稍后說

完善布局

添加背景動畫

由于MotionLayout是ConstraintLayout的子類,所以我們可以像使用ConstraintLayout一樣使用它.我們先來將背景添加上,代碼如下:
activity_main.xml中:

    <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中:

 <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定義了動畫開始的狀態(tài);id為end的Constraint的則定義了動畫結(jié)束的狀態(tài),Constraint標(biāo)簽用來描述一個控件的位置和屬性,但光有這些還不夠,我們還需要添加一個動畫的觸發(fā)方式,這里有兩種觸發(fā)方式:

  • <OnClick>標(biāo)簽表示點(diǎn)擊觸發(fā)動畫
  • <OnSwipe>標(biāo)簽表示拖拽執(zhí)行動畫
    這里我們選擇后者:<OnSwipe>標(biāo)簽要放在Transition標(biāo)簽中,代碼如下:
    <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>

解釋下相關(guān)的屬性

  • dragDirection 拖拽的方向
  • touchAnchorId 滑動影響的控件id
  • touchAnchorSide 滑動所固定到的目標(biāo)視圖的一側(cè),可以配合dragDirection理解,二者相反

在xml布局文件和motionscene的文件中,控件的id不能少,Constraint標(biāo)簽中l(wèi)ayout_打頭的屬性都要有,其余可以省略比如src屬性,因?yàn)樵趚ml中已經(jīng)賦值了

我們現(xiàn)在看一下效果,可以在design面板中先預(yù)覽一下:


image.png

點(diǎn)擊1所指的start可以預(yù)覽start狀態(tài)规哪,點(diǎn)擊2所指的end預(yù)覽end狀態(tài)求豫。點(diǎn)擊上方3所指的連線,可以在下方面板點(diǎn)擊播放鍵查看動畫,當(dāng)然也可以自己拖拽查看。

image.png

我們直接運(yùn)行看效果吧:


image.gif
添加右下方收藏按鈕等動畫

activity_main.xml代碼:

   <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代碼:

  <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"可以在手機(jī)上看到動畫的移動軌跡,我們加入一下

運(yùn)行看效果:


image2.gif

但是我們看這個收藏按鈕的運(yùn)動軌跡有點(diǎn)單調(diào),就是直線從A點(diǎn)到B點(diǎn).我們來改進(jìn)一下,這就需要用到我們上面提到的 KeyFrameSet了,KeyFrameSet包含于Transition標(biāo)簽中蝠嘉,這個標(biāo)簽用來描述一系列運(yùn)動過程中的關(guān)鍵幀最疆。我們可以利用其使動畫效果變的更復(fù)雜。其子元素包含KeyPosition蚤告、KeyAttribute等,我們先使用一下其子元素KeyPosition(因?yàn)橐淖兊氖沁\(yùn)動軌跡),具體的用法如下:

activity_main_scene.xml代碼:

     <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>

運(yùn)行效果如下:


image3.gif

通過設(shè)置app:showPaths="true"我們可以很明顯的看到運(yùn)動軌跡發(fā)生了變化.
關(guān)鍵屬性說明如下:

  • motionTarget 受影響的控件id
  • framePosition 關(guān)鍵幀的位置取值為1 到 99 之間的整數(shù)努酸。這里取值50就是指動畫進(jìn)行到一半的位置
  • percentX和 percentY 控件到達(dá)framePosition點(diǎn)時的位置,是個float值杜恰。這兩個屬性的具體意義需要根據(jù)keyPositionType的類型來定
  • keyPositionType 有多種取值,以我們代碼中為例motion:keyPositionType="deltaRelative",取值為deltaRelative時:percentX 和 percentY 坐標(biāo)系以constraintSetStart指定的位置為原點(diǎn)获诈,X軸平行于父布局X軸,方向?yàn)閯赢嬮_始的x點(diǎn)指向結(jié)束點(diǎn)x點(diǎn)心褐,其值0為原點(diǎn)舔涎,1為動畫整個動畫X軸方向的運(yùn)動距離。Y軸平行于父布局Y軸逗爹,方向?yàn)閯赢嬮_始的y點(diǎn)指向結(jié)束點(diǎn)y點(diǎn)亡嫌,其值0為原點(diǎn),1為動畫整個動畫Y軸方向的運(yùn)動距離掘而。如下:
    image.png
關(guān)注按鈕

注意:關(guān)注按鈕的控件大小和字體大小的變化,運(yùn)動過程中也伴隨著漸變效果.這樣的效果我們就需要用的KeyFrameSet中的另一個子元素KeyAttribute以及Constraint 中的CustomAttribute標(biāo)簽配合完成.

activity_main.xml相關(guān)代碼如下:

 <Button
        android:id="@+id/btn_attention"
        android:layout_width="110dp"
        android:layout_height="50dp"
        android:textSize="18sp"
        android:text="關(guān)注我 +"
        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相關(guān)代碼如下:

<!-- 設(shè)置關(guān)注按鈕不同幀漸變-->
<!-- 用到了兩個KeyAttribute每個控件使用了兩個挟冠,是因?yàn)橐獙?shí)現(xiàn)在動畫的中間部分保持0.0的透明度不變,在快要結(jié)束時再變得可見袍睡。-->
           <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狀態(tài)

        <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狀態(tài)

       <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

相關(guān)屬性說明:
關(guān)于Constraint
Constraint:每一個Constraint元素對應(yīng)一個id屬性所指向的View,我們必須為控件設(shè)置寬和高即使在布局xml中已經(jīng)設(shè)置過了.

  • id :用來指定布局中對應(yīng)的view
  • CustomAttribute: 包含在Constraint元素中知染,一個 <CustomAttribute> 本身包含兩個屬性
    1.motion:attributeName 是必需屬性,并且必須與控件中具有 getter 和 setter 方法的屬性相對應(yīng)女蜈。
    2.第二個屬性我們需要基于上面填寫的屬性來決定。比如上面填寫的backgroundColor這里我們就需要使用customColorValue色瘩。

關(guān)于KeyAttribute
指定動畫序列中特定時刻的視圖屬性伪窖。
motionTarget 和framePosition 與KeyPosition意義相同
KeyAttribute還支持visibility、rotation居兆、scale等控件基本屬性。

最后附上所有代碼
activity_main.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"
    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"-->
    <!--背景圖片-->

    <!--    用戶信息區(qū)域-->
    <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="關(guān)注 +"
        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="請說點(diǎn)什么吧"
        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 這個標(biāo)簽用來描述一系列運(yùn)動過程中的關(guān)鍵幀-->
            <!--            KeyPosition用來指定動畫序列中特定時刻的位置-->
            <!--            motion:motionTarget表示受影響的控件id-->
            <!--            motion:framePosition 取值為1 到 99 之間的整數(shù)。這里取值50就是指動畫進(jìn)行到一半的位置 -->
            <!--            motion:percentX和motion:percentY是控件到達(dá)motion:framePosition點(diǎn)時的位置辫樱,是個float值弧满。-->
            <!--            這兩個屬性的具體意義需要根據(jù)motion:keyPositionType的類型來定-->

            <!--            給收藏和分享調(diào)整運(yùn)動軌跡-->
            <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" />

            <!--          給頭像和名字設(shè)置漸變效果-->
            <!--            動畫的中間部分保持0.2的透明度不變,在快要結(jié)束時再變得可見-->
            <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" />


            <!--            給關(guān)注按鈕調(diào)整效果-->
            <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里的屬性可以不用寫已經(jīng)在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 方法的屬性相對應(yīng)-->
            <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,關(guān)于MotionLayout就說這么多,更詳細(xì)的內(nèi)容推薦大家去查看官方文檔或者其它資料.



















最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吧享,一起剝皮案震驚了整個濱河市魏割,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钢颂,老刑警劉巖钞它,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡遭垛,警方通過查閱死者的電腦和手機(jī)尼桶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锯仪,“玉大人泵督,你說我怎么就攤上這事∈玻” “怎么了小腊?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長溃卡。 經(jīng)常有香客問我溢豆,道長,這世上最難降的妖魔是什么瘸羡? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任漩仙,我火速辦了婚禮,結(jié)果婚禮上犹赖,老公的妹妹穿的比我還像新娘队他。我一直安慰自己,他們只是感情好峻村,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布麸折。 她就那樣靜靜地躺著,像睡著了一般粘昨。 火紅的嫁衣襯著肌膚如雪垢啼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天张肾,我揣著相機(jī)與錄音芭析,去河邊找鬼。 笑死吞瞪,一個胖子當(dāng)著我的面吹牛馁启,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芍秆,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼惯疙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了妖啥?” 一聲冷哼從身側(cè)響起霉颠,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荆虱,沒想到半個月后掉分,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俭缓,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年酥郭,在試婚紗的時候發(fā)現(xiàn)自己被綠了华坦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡不从,死狀恐怖惜姐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情椿息,我是刑警寧澤歹袁,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站寝优,受9級特大地震影響条舔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乏矾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一孟抗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钻心,春花似錦凄硼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至痒给,卻和暖如春说墨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背苍柏。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工尼斧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人序仙。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓突颊,卻偏偏與公主長得像鲁豪,于是被迫代替她去往敵國和親潘悼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容