MotionLayout 基礎教程

閱讀說明:php

  • 本文假設讀者已掌握如何使用 ConstraintLayout
  • 本文是一篇 MotionLayout 基礎教程,如您已瞭解如何使用 MotionLayout,本文可能對您幫助不大。
  • 本教程共有兩篇文章,這是第一篇,另外一篇請點擊 這裏
  • 建議讀者跟隨本文一塊兒動手操做,如您如今不方便,建議稍後閱讀。
  • 本文基於 ConstraintLayout 2.0.0-alpha4 版本編寫,建議讀者優先使用這一版本。
  • 因爲 MotionLayout 官方文檔不全,有些知識點是根據筆者本身的理解總結的,若有錯誤,歡迎指正。

添加支持庫:html

dependencies {
    ...
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha4'
}
複製代碼

MotionLayout 最低支持到 Android 4.3(API 18),還有就是 MotionLayoutConstraintLayout 2.0 添加的,所以必須確保支持庫的版本不低於 2.0java

簡介

MotionLayout 類繼承自 ConstraintLayout 類,容許你爲各類狀態之間的佈局設置過渡動畫。因爲 MotionLayout 繼承了 ConstraintLayout,所以能夠直接在 XML 佈局文件中使用 MotionLayout 替換 ConstraintLayoutandroid

MotionLayout 是徹底聲明式的,你能夠徹底在 XML 文件中描述一個複雜的過渡動畫而 無需任何代碼(若是您打算使用代碼建立過渡動畫,那建議您優先使用屬性動畫,而不是 MotionLayout)。app

開始使用

因爲 MotionLayout 類繼承自 ConstraintLayout 類,所以能夠在佈局中使用 MotionLayout 替換掉 ConstraintLayout框架

MotionLayoutConstraintLayout 不一樣的是,MotionLayout 須要連接到一個 MotionScene 文件。使用 MotionLayoutapp:layoutDescription 屬性將 MotionLayout 連接到一個 MotionScene 文件。ide

例:佈局

<?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/scene_01">
    
    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

注意!必須爲 MotionLayout 佈局的全部直接子 View 都設置一個 Id(容許不爲非直接子 View 設置 Id)。post

建立 MotionScene 文件

MotionScene 文件描述了兩個場景間的過渡動畫,存放在 res/xml 目錄下。gradle

要使用 MotionLayout 建立過渡動畫,你須要建立兩個 layout 佈局文件來描述兩個不一樣場景的屬性。當從一個場景切換到另外一個場景時,MotionLayout 框架會自動檢測這兩個場景中具備相同 idView 的屬性差異,而後針對這些差異屬性應用過渡動畫(相似於 TransitionManger)。

MotionLayout 框架支持的標準屬性:

  • android:visibility
  • android:alpha
  • android:elevation
  • android:rotation
  • android:rotationX
  • android:rotationY
  • android:scaleX
  • android:scaleY
  • android:translationX
  • android:translationY
  • android:translationZ

MationLayout 除了支持上面列出的標準屬性外,還支持所有的 ConstraintLayout 屬性。

下面來看一個完整的例子,這個例子分爲如下 3 步。

1 步:建立場景 1 的佈局文件:

文件名:activity_main_scene1.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/motionLayout" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

場景 1 的佈局預覽以下圖所示:

2 步:建立場景 2 的佈局文件:

文件名:activity_main_scene2.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

場景 2 的佈局預覽以下圖所示:

說明:場景 1 與場景 2 中都有一個 id 值爲 imageImageView,它們的差異是:場景 1 中的 image 是水平垂直居中放置的,而場景 2 中的 image 是水平居中,垂直對齊到父佈局頂部的。所以當從場景 1 切換到場景 2 時,MotionLayout 將針對 image 的位置差異自動應用位移過渡動畫。

3 步:建立 MotionScene 文件:

文件名:activity_main_motion_scene.xml,存放在 res/xml 目錄下

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition app:constraintSetStart="@layout/activity_main_scene1" app:constraintSetEnd="@layout/activity_main_scene2" app:duration="1000">

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

    </Transition>

</MotionScene>
複製代碼

編寫完 MotionLayout 文件後就能夠直接運行程序了。點擊 image 便可進行場景切換。當進行場景切換時,MotionLayout 會自動計算出兩個場景之間的差異,而後應用相應的過渡動畫。

MotionLayout Demo

下面對 MotionLayout 文件進行說明:

如上例所示,MotionScene 文件的根元素是 <MotionScene>。在 <MotionScene> 元素中使用 <Transition> 子元素來描述一個過渡,使用 <Transition> 元素的 app:constraintSetStart 屬性指定起始場景的佈局文件,使用 app:constraintSetEnd 指定結束場景的佈局文件。在 <Transition> 元素中使用 <OnClick> 或者 <OnSwip> 子元素來描述過渡的觸發條件。

<Transition> 元素的屬性:

  • app:constraintSetStart:設置爲起始場景的佈局文件 Id
  • app:constraintSetEnd:設置爲結束場景的佈局文件 Id
  • app:duration:過渡動畫的持續時間。
  • app:motionInterpolator:過渡動畫的插值器。共有如下 6 個可選值:
    • linear:線性
    • easeIn:緩入
    • easeOut:緩出
    • easeInOut:緩入緩出
    • bounce:彈簧
    • anticipate:(功能未知,沒有找到文檔)
  • app:staggered:【浮點類型】(功能未知,沒有找到文檔)

能夠在 <Transition> 元素中使用一個 <OnClick> 或者 <OnSwipe> 子元素來描述過渡的觸發條件。

<OnClick> 元素的屬性:

  • app:targetId:【id 值】設置用來觸發過渡的那個 ViewId(例如:@id/image@+id/image)。

提示app:targetId 的值的前綴既能夠是 @+id/ 也能夠是 @id/,二者均可以。官方示例中使用的是 @+id/。不過,使用 @id/ 前綴彷佛更加符合語義,由於 @+id/ 前綴在佈局中經常使用來建立一個新的 Id,而 @id/ 前綴則經常使用來引用其餘的 Id 值。爲了突出這裏引用的是其餘的 Id 而不是新建了一個 Id,使用 @id/ 前綴要更加符合語義。

  • app:clickAction:設置點擊時執行的動做。該屬性共有如下 5 個可選的值:
    • toggle:在 Start 場景和 End 場景之間循環的切換。
    • transitionToEnd:過渡到 End 場景。
    • transitionToStart:過渡到 Start 場景。
    • jumpToEnd:跳到 End 場景(不執行過渡動畫)。
    • jumpToStart:跳到 Start 場景(不執行過渡動畫)。

<OnSwipe> 元素的屬性:

  • app:touchAnchorId:【id 值】設置拖動操做要關聯到的對象,讓觸摸操做看起來像是在拖動這個對象的由 app:touchAnchorSide 屬性指定的那個邊。
  • app:touchAnchorSide:設置觸摸操做將會拖動對象的哪一邊,共有如下 4 個可選值:
    • top
    • left
    • right
    • bottom
  • app:dragDirection:設置拖動的方向(注意,只有設置了 app:touchAnchorId 屬性後該屬性纔有效)。共有如下 4 個可選值:
    • dragUp:手指從下往上拖動(↑)。
    • dragDown:手指從上往下拖動(↓)。
    • dragLeft:手指從右往左拖動(←)。
    • dragRight:手指從左往右拖動(→)。
  • app:maxVelocity:【浮點值】設置動畫在拖動時的最大速度(單位:像素每秒 px/s)。
  • app:maxAcceleration:【浮點值】設置動畫在拖動時的最大加速度(單位:像素每二次方秒 px/s^2)。

能夠同時設置 <OnClick><OnSwipe> ,或者都不設置,而是使用代碼來觸發過渡。

還能夠在 <Transition> 元素中設置多個 <OnClick>,每一個 <OnClick> 均可以關聯到一個不一樣的控件上。雖然 <Transition> 元素中也能夠設置多個 <OnSwipe>,可是後面的 <OnSwipe> 會替換掉前面的 <OnSwipe>,最終使用的是最後一個 <OnSwipe>

<OnSwipe> 拖動操做

因爲 <OnSwipe> 拖動操做涉及的交互較爲複雜,這裏單獨對它的如下 3 個屬性進行說明:

  • app:touchAnchorId
  • app:dragDirection
  • app:touchAnchorSide

首先是 app:touchAnchorId 屬性與 app:dragDirection 屬性。app:touchAnchorId 屬性用於設置拖動操做要關聯到的對象;app:dragDirection 屬性用於指定拖動方向。

默認狀況下,由上往下 拖動時會運行過渡動畫,此時 <OnSwipe/> 元素不須要設置任何屬性,只要在 <Transition> 中加一個 <OnSwipe/> 標籤便可。

例:

<Transition ...>

    <OnSwipe/>

</Transition>
複製代碼

可是,若是你要支持 由下往上(↑)或者 由左往右(→)或者 由右往左(←),那麼至少應該設置好 app:touchAnchorIdapp:dragDirection 屬性。

app:dragDirection 屬性設置的拖動方向與 app:touchAnchorId 屬性關聯到的對象在 Start 場景和 End 場景中的位置是息息相關的。例以下圖 a 中,End 場景中的 Widget 位於 Start 場景中的 Widget 的上方,那麼應該設置 app:dragDirection="dragUp"。再看圖 b 中,End 場景中的 Widget 位於 Start 場景中的 Widget 的右邊,那麼應該設置 app:dragDirection="dragRight"

若是 End 場景中的 Widget 相對於 Start 場景中的 Widget 是傾斜的(以下圖所示),將會有兩個可選的方向,下圖中的可選方向是 dragUpdragRight,具體使用哪一個方向,由你本身決定。

設置一個正確的拖動方向是很是重要的,不然拖動時,過渡動畫將表現不佳。

提示MotionLayout 將使用 app:touchAnchorId 關聯到的對象在 app:dragDirection 方向上的拖動進度(progress)做爲整個過渡動畫的進度,當關聯對象在 app:dragDirection 方向上的拖動完成時,也就意味着整個過渡動畫完成了。

:實現拖動效果

刪除 <Transition> 元素元素的 <OnClick> 標籤,並加入一個 <OnSwipe> 標籤,修改後的 MotionScene 文件內容以下所示:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition app:constraintSetStart="@layout/activity_main_scene1" app:constraintSetEnd="@layout/activity_main_scene2" app:duration="1000">

        <!-- 刪除 OnClick,加入 OnSwipe -->
        
        <OnSwipe app:touchAnchorId="@id/image" app:dragDirection="dragUp"/>

    </Transition>

</MotionScene>
複製代碼

注意:若是將 <OnClick><OnSwipe> 關聯到了同一個控件,或者 <OnSwipe> 關聯到的那個控件是可點擊的,點擊事件將會影響到拖動,你將沒法按住控件進行拖動,只能按住控件的外面才能拖動。

<Transition> 標籤中加入 <OnClick>,修改後的 MotionScene 文件內容以下所示:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition app:constraintSetStart="@layout/activity_main_scene1" app:constraintSetEnd="@layout/activity_main_scene2" app:duration="1000">

        <OnSwipe app:touchAnchorId="@id/image" app:dragDirection="dragUp"/>

        <!-- 加入 OnClick -->
        <OnClick app:targetId="@id/image" app:clickAction="toggle"/>

    </Transition>

</MotionScene>
複製代碼

效果以下所示:

app:touchAnchorSide 屬性:

app:touchAnchorSide 屬性的功能是 「設置觸摸操做將會拖動對象的哪一邊」,該屬性可用於實現可摺疊效果,例如可摺疊標題欄。

:在底部實現一個向上拉的摺疊效果。

1. 修改 acticity_main_scene1.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/motionLayout" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

    <!-- 增長如下代碼 -->
    <FrameLayout android:id="@+id/bottomBar" android:layout_width="match_parent" android:layout_height="0dp" android:background="@color/colorPrimary" app:layout_constraintTop_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent">

        <ImageView android:layout_gravity="center" android:src="@mipmap/ic_launcher" android:layout_width="wrap_content" android:layout_height="wrap_content"/>

    </FrameLayout>

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

2. 修改 acticity_main_scene2.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

    <!-- 增長如下代碼 -->
    <FrameLayout android:id="@+id/bottomBar" android:layout_width="match_parent" android:layout_height="120dp" android:background="@color/colorPrimary" app:layout_constraintBottom_toBottomOf="parent">

        <ImageView android:layout_gravity="center" android:src="@mipmap/ic_launcher" android:layout_width="wrap_content" android:layout_height="wrap_content"/>

    </FrameLayout>

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

3. 修改 MotionScene 文件(文件名:activity_main_motion_scene.xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition app:constraintSetStart="@layout/activity_main_scene1" app:constraintSetEnd="@layout/activity_main_scene2" app:duration="1000">

        <!-- 關聯到 bottomBar 上-->
        <OnSwipe app:touchAnchorId="@id/bottomBar" app:touchAnchorSide="top" app:dragDirection="dragUp"/>

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

    </Transition>

</MotionScene>
複製代碼

效果以下所示:

提示:其實 <OnSwipe> 能夠不關聯到 bottomBar 上,在由於在前面的例子中咱們已經把 <OnSwipe> 關聯到了 image 上,且拖動方向也設置正確(drageUp),這樣其實已經能夠正常拖動了。可是因爲 bottomBar 是可摺疊的,把 <OnSwipe> 拖動關聯到它上面更加合適,這樣能夠設置 app:touchAnchorSide="top",告訴 MotionLayout 控件 bottomBar 的上邊界是可拖動的,這樣更符合語義。

使用代碼觸發過渡動畫

除了使用 <OnClick> 元素與 <OnSwipe> 元素來設置觸發過渡動畫的觸發條件外,還可使用代碼來手動觸發過渡動畫。

下面對場景 1 的佈局文件進行修改,在佈局中添加 2 個按鈕,預覽以下圖所示:

場景 1 修改後的佈局文件內容爲:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

    <Button android:id="@+id/btnToStartScene" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="To Start Scene" android:textAllCaps="false" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/btnToEndScene" />

    <Button android:id="@+id/btnToEndScene" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="To End Scene" android:textAllCaps="false" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/btnToStartScene" app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

場景 2 的佈局文件不須要修改。

MainActivity 中添加以下代碼來手動執行過渡動畫:

public class MainActivity extends AppCompatActivity {
    private MotionLayout mMotionLayout;
    private Button btnToStartScene;
    private Button btnToEndScene;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_scene1);

        mMotionLayout = findViewById(R.id.motionLayout);
        btnToStartScene = findViewById(R.id.btnToStartScene);
        btnToEndScene = findViewById(R.id.btnToEndScene);

        btnToStartScene.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 切換到 Start 場景
                mMotionLayout.transitionToStart();
            }
        });

        btnToEndScene.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 切換到 End 場景
                mMotionLayout.transitionToEnd();
            }
        });
    }
}
複製代碼

如上面代碼中所示,調用 MotionLayouttransitionToStart() 方法能夠切換到 Start 場景,調用 MotionLayouttransitionToStart() 方法能夠切換到 End 場景。

效果以下所示:

調整過渡動畫的進度

MotionLayout 還支持手動調整過渡動畫的播放進度。使用 MotionLayoutsetProgress(float pos) 方法(pos 參數的取值範圍爲 [0.0 ~ 1.0])來調整過渡動畫的播放進度。

下面對場景 1 的佈局文件進行修改,移除兩個按鈕,加入一個 SeekBar,修改後的佈局代碼以下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_motion_scene">

    <ImageView android:id="@+id/image" android:layout_width="48dp" android:layout_height="48dp" android:src="@mipmap/ic_launcher" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

    <SeekBar android:id="@+id/seekBar" android:layout_width="240dp" android:layout_height="wrap_content" android:layout_marginBottom="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼

佈局預覽以下圖所示:

修改 MainActivity 中的代碼:

public class MainActivity extends AppCompatActivity {
    private MotionLayout mMotionLayout;
    private SeekBar mSeekBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_scene1);

        mMotionLayout = findViewById(R.id.motionLayout);
        mSeekBar = findViewById(R.id.seekBar);

        mSeekBar.setMax(0);
        mSeekBar.setMax(100);
        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mMotionLayout.setProgress((float) (progress * 0.01));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}
複製代碼

效果以下圖所示:

監聽 MotionLayout 過渡

能夠調用 MotionLayoutsetTransitionListener() 方法向 MotionLayout 對象註冊一個過渡動畫監聽器,這個監聽器能夠監聽過渡動畫的播放進度和結束事件。

public void setTransitionListener(MotionLayout.TransitionListener listener) 複製代碼

TransitionListener 監聽器接口:

public interface TransitionListener {
    // 過渡動畫正在運行時調用
    void onTransitionChange(MotionLayout motionLayout, int startId, int endId, float progress);
    // 過渡動畫結束時調用
    void onTransitionCompleted(MotionLayout motionLayout, int currentId);
}
複製代碼

提示TransitionListener 接口在 alpha 版本中有所改動,可多出了 2 個回調方法:onTransitionStartedonTransitionTrigger。因爲 MotionLayout 還處於 alpha 版本,並未正式發佈,所以有所改動也是正常。

例:

MotionLayout motionLayout = findViewById(R.id.motionLayout);
motionLayout.setTransitionListener(new MotionLayout.TransitionListener() {
    @Override
    public void onTransitionChange(MotionLayout motionLayout, int i, int i1, float v) {
        Log.d("App", "onTransitionChange: " + v);
    }

    @Override
    public void onTransitionCompleted(MotionLayout motionLayout, int i) {
        Log.d("App", "onTransitionCompleted");
    }
});
複製代碼

結語

本篇文章到此就結束了,你可能會以爲前面的例子不夠炫酷,這裏給出一個炫酷點的例子(這個例子很簡單,建議讀者動手嘗試實現一下):

MotionLayout Cool Demo

後續文章:

參考文章:

相關文章
相關標籤/搜索