閱讀說明:php
ConstraintLayout
。MotionLayout
有了基本瞭解,知道如何建立 MotionScene
文件,以及如何使用 MotionLayout
在兩個 layout
佈局文件間建立過渡動畫。如您徹底不瞭解這些,建議您閱讀 《MotionLayout 基礎教程》。本文是 《MotionLayout 基礎教程》 的第 2
篇,主要向讀者介紹如何在 MotionScene
文件中定義場景約束以及如何使用自定義屬性。android
能夠在 <MotionScene>
元素中使用 <ConstraintSet>
子元素定義一個場景約束集,並在 <ConstraintSet>
元素中使用 <Constraint>
元素定義單個 View
的屬性約束。app
例:在 MotionScene
文件中定義 End
場景的約束集框架
<?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">
<!-- 定義 End 場景的約束集 -->
<ConstraintSet android:id="@+id/activity_main_end">
<!-- 定義佈局中 id 爲 image 的 View 的屬性約束 -->
<Constraint android:id="@+id/button" android:layout_width="56dp" android:layout_height="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" />
</ConstraintSet>
<!-- Start 場景是佈局文件,End 場景是定義在 MotionScene 文件中的約束集 -->
<Transition app:constraintSetStart="@layout/activity_main" app:constraintSetEnd="@id/activity_main_end" app:duration="1000">
<OnClick app:clickAction="toggle" app:targetId="@id/button" />
</Transition>
</MotionScene>
複製代碼
實際上,你便可以把 Start
場景的約束集定義在 MotionScene
文件中,也能夠把 End
場景的約束集定義在 MotionScene
文件中。或者僅在 MotionScene
文件中定義這二者之一,另外一個場景使用 layout
佈局文件定義。佈局
建議:建議把
Start
場景和End
場景的約束集都定義在MotionScene
文件中。由於MotionLayout
框架某些特性(例如自定義屬性(下節會介紹))依賴於MotionScene
文件中Start
場景,若是Start
場景沒有定義在MotionScene
文件中,這些特性可能會沒法使用。post
例:在 MotionScene
文件中定義 Start
場景約束與 End
場景約束(本示例分爲如下兩步)學習
1. 建立佈局文件:測試
文件名:
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" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/activity_main_motion_scene">
<Button android:id="@+id/button" android:layout_width="56dp" android:layout_height="56dp" android:background="@color/colorPrimary" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.motion.widget.MotionLayout>
複製代碼
提示:佈局文件仍是要有的,並非說將
Start
場景約束和End
場景約束都定義在了MotionScene
文件中就能夠不須要佈局文件了。spa
佈局文件預覽:
2. 建立 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">
<!-- 定義 Start 場景的屬性約束集 -->
<ConstraintSet android:id="@+id/activity_main_start">
<!-- 定義佈局中 id 爲 button 的 View 的屬性約束 -->
<Constraint android:id="@id/button" android:layout_width="56dp" android:layout_height="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0" />
</ConstraintSet>
<!-- 定義 End 場景的屬性約束集 -->
<ConstraintSet android:id="@+id/activity_main_end">
<!-- 定義佈局中 id 爲 button 的 View 的屬性約束 -->
<Constraint android:id="@+id/button" android:layout_width="56dp" android:layout_height="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" />
</ConstraintSet>
<!-- Start 場景與 End 場景都是定義在 MotionScene 文件中的約束集 -->
<Transition app:constraintSetStart="@id/activity_main_start" app:constraintSetEnd="@id/activity_main_end" app:duration="1000">
<OnClick app:clickAction="toggle" app:targetId="@id/button" />
</Transition>
</MotionScene>
複製代碼
<ConstraintSet>
元素屬性說明:
android:id
:設置當前約束集的 id
。這個 id
值可被 <Transition>
元素的 app:constraintSetStart
或者 app:constraintSetEnd
引用。<Constraint>
元素屬性說明:
android:id
:當前約束關聯到的那個 View
的 id
。app:transitionEasing
:定義動畫到此點時使用的緩動曲線,該值能夠是一個字符串(例如 "curve(1.0,0,0,1.0)"
)還能夠是如下幾個枚舉值之一:
standard
:標準accelerate
:加速decelerate
:減速linear
:線性提示
1
:<Constraint>
元素的app:transitionEasing
屬性與<Transition>
元素的app:motionInterpolator
屬性相似,都是用來定義過渡動畫的插值器的。不一樣的是,<Constraint>
元素的app:transitionEasing
屬性定義的是單獨某個View
的過渡動畫的插值器,而<Transition>
元素的app:motionInterpolator
定義的是整個過渡動畫的插值器。
提示
2
:若是爲<Constraint>
元素指定了app:transitionEasing
插值器,這個插值器將與app:motionInterpolator
屬性指定的全局插值器同時做用於View
的過渡動畫,而不是替換掉app:motionInterpolator
屬性指定的全局插值器。
提示
3
:<Constraint>
元素的app:transitionEasing
屬性值應該在Start
場景中指定,(經測試)僅在End
場景中指定app:transitionEasing
沒法生效。
提示
4
:(經測試,彷佛無效)可使用形如"curve(1.0,0,0,1.0)"
的字符串來爲<Constraint>
元素的app:transitionEasing
屬性設置一個緩動曲線,MotionLayout
框架將根據這個緩動曲線來生成一個插值器。
app:transitionPathRotate
:【浮點值】相對於所採用的路徑旋轉對象(弧形路徑/關鍵幀 相關)。app:drawPath
:繪製過渡動畫路徑(調試用,關鍵幀相關)。能夠是如下幾個枚舉值之一:
none
path
pathRelative
deltaRelative
asConfigured
rectangles
app:progress
:【浮點值】在關聯的 View
上調用 setProgress(float)
方法(用於與嵌套的 ConstraintLayout
交互)前面說過,<Constraint>
元素用來定義單個 View
的屬性約束,它支持對 View
的全部 ConstraintLayout
屬性定義約束,以及對 View
的下面這些標準屬性定義約束:
android:visibility
android:alpha
android:elevation
android:rotation
android:rotationX
android:rotationY
android:scaleX
android:scaleY
android:translationX
android:translationY
android:translationZ
當 View
的標準屬性或者 ConstraintLayout
屬性發生改變時,MotionLayout
會自動應用過渡動畫。
MotionLayout
控件只會檢測標準屬性和 ConstraintLayout
屬性這類佈局相關的屬性變更,對於其餘的屬性變更,如 View
的背景顏色變更是沒法檢測出來的,所以就須要使用自定義屬性。
在 <Constraint>
元素中使用 <CustomAttribute>
子元素來指定自定義屬性。
例:
<?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">
<!-- 定義 Start 場景的屬性約束集 -->
<ConstraintSet android:id="@+id/activity_main_start">
<!-- 定義佈局中 id 爲 image 的 View 的屬性約束 -->
<Constraint android:id="@id/button" android:layout_width="56dp" android:layout_height="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0">
<!-- 使用自定義屬性 -->
<CustomAttribute app:attributeName="backgroundColor" app:customColorValue="@color/colorPrimary" />
</Constraint>
</ConstraintSet>
<!-- 定義 End 場景的屬性約束集 -->
<ConstraintSet android:id="@+id/activity_main_end">
<!-- 定義佈局中 id 爲 image 的 View 的屬性約束 -->
<Constraint android:id="@+id/button" android:layout_width="56dp" android:layout_height="56dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0">
<!-- 使用自定義屬性 -->
<CustomAttribute app:attributeName="backgroundColor" app:customColorValue="@color/colorAccent" />
</Constraint>
</ConstraintSet>
<Transition app:constraintSetEnd="@id/activity_main_end" app:constraintSetStart="@id/activity_main_start" app:duration="1000">
<OnClick app:clickAction="toggle" app:targetId="@id/button" />
</Transition>
</MotionScene>
複製代碼
效果預覽:
<CustomAttribute>
元素屬性說明:
app:attributeName
屬性用來指定自定義屬性的名字(例如 "backgroundColor"
)。關聯的 View
必需要有一對與這個名字相關的 getter/setter
方法(例如 getBackgroundColor()/setBackgroundColor(int color)
)。XML
屬性之一來設置自定義屬性的值:
app:customColorValue
:設置屬性的值(顏色類型)。app:customColorDrawableValue
:設置屬性的值(顏色類型)。app:customIntegerValue
:設置屬性的值(整數類型)。app:customFloatValue
:設置屬性的值(浮點類型)。app:customStringValue
:設置屬性的值(字符串類型)。app:customDimension
:設置屬性的值(尺寸類型)。app:customPixelDimension
:設置屬性的值(尺寸類型)。app:customBoolean
:設置屬性的值(布爾類型)。本篇文章是 《MotionLayout 基礎教程》 的第 2
篇,閱讀完這兩篇文章後您基本就能掌握 MotionLayout
的基礎內容了。
寫這兩篇文章的主要目的是爲了向讀者介紹 MotionLayout
的基礎內容,讓讀者可以入門,並在此基礎上進一步學習。如您想要了解更多 MotionLayout
內容,推薦您閱讀如下 3
篇文章: