MotionLayout
是ConstrainLayout 2.0
庫中被引入的一個新類,幫助安卓開發者關聯手勢和組件動畫。接下來的文章將介紹會如何在應用中添加和使用MotionLayout
。java
第一章將介紹MotionLayout的基礎:android
MotionLayout
是什麼?ConstrainLayout 2.0
和MotionLayout
添加到項目中MotionLayout
ConstraintSets
MotionScene
你能夠在這裏查看示例的源碼ConstraintLayout examples github repositorgit
安卓系統框架中已經提供下面幾種方法在應用中使用動畫:github
這一部分將介紹MotionLayout
與這些動畫的不一樣。MotionLayout
就像它的名字同樣,首先它是一個佈局,能夠放置組件。其次它仍是ConstrainLayout
的子類,內置豐富的功能。建立MotionLayout
的目的是用於下降佈局過渡動畫和複雜的手勢處理之間的難度,你能夠認爲它擁有綜合屬性動畫TransitionManager
,和CoordinatorLayout
的功能。面試
它擁有綜合屬性動畫TransitionManager
,和CoordinatorLayout
的功能
使用MotionLayout
你能夠像TransitionManager
同樣經過兩個佈局文件描述佈局的過渡動畫,可是可使用任何屬性(不只僅局局於佈局屬性)。還有它支持可循跡的過渡,就像CoordinatorLayout
(能夠經過滑動即刻響應過渡動畫)。它支持經過滑動和關鍵幀自定義過渡動畫。架構
MotionLayout
的另一個關鍵區別是,它是徹底聲明式的。只須要XML文件就能夠描述一個複雜的過渡動畫(若是你像經過代碼來描述動畫,系統提供的屬性徹底能夠知足需求)。app
咱們相信這種聲明式的規範將簡化過渡動畫,同時也有助於爲 Android Studio 提供更好的圖形化工具。(咱們如今正在積極的開發這樣的工具,它如今還不可用。)框架
最後,做爲ConstrainLayout 2.0的一部分,它最低支持安卓API 14,99.8%的設備均可以使用。ide
不一樣於TransitionManager
,MotionLayout
只能用於他的直接子組件。工具
咱們設想到的使用MotionLayou
t的使用場景:當你須要移動,縮放或者動畫實際的UI組件(按鈕,標題欄等)來提供與用戶的互動時。
將ConstrainLayout 2.0和MotionLayout添加到項目中,只須要將下面的代碼添加到Gradle文件中便可
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1' }
MotionLayout
是ConstrainLayout
的子類,所以你能夠把它看成一個普通的佈局。將已經存在的ConstrainLayout
佈局轉換成MotionLayout
佈局只須要將類名從:
<android.support.constraint.ConstraintLayout .../>
替換成
<android.support.constraint.motion.MotionLayout .../>
ConstrainLayou
t和MotionLayout
的主要不一樣是MotionLayout
不是必須將實際描述信息包含在XML佈局文件中。MotionLayout
一般將這些信息保存在一個單獨的XML文件(MotionScene
)中並關聯到佈局文件,經過這種方式佈局文件只須要包含它們的屬性,無需包含位置信息和動畫。
一般ConstrainSet
將全部遊戲佈局文件中的全部的位置信息規則; 你可使用多個ConstrainSet
,你能夠決定將那些規則應用到佈局中,在應用時這些查看不會被重建,只會修改他們的位置和大小。結合TransitionManager
使用能夠很容易的建立ConstrainLayout
的動畫。MotionLayout
實際上也是源於這種思想,並添加了更豐富的功能。
MotionLayout
的規範保存在一個單獨的MotionScene
XML文件中,文件該存儲在res / xml
目錄中。
一個MotionScene
文件能夠全部遊戲動畫所需的所用內容:
ConstraintSets
ConstraintSet
之間的轉換(過渡)例如,你能夠將一個查看從屏幕的一側拖拽到另外一側:
須要你使用ConstrainLayout
建立³³兩個ConstrainSet
一個的英文初始位置(組件在屏幕的左面)一個是結束位置(組件在屏幕的右邊)
初始位置:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
結束位置:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
使用這兩個佈局文件能夠初始化兩個ConstrainSet
,並使用他們(使用若是TransitionManager
會有動畫的平滑過渡)。這種方式有一個問題是轉化一旦開始就不會結束,你也不能告訴系統將轉換挺在某個位置(你不能經過輸入事件控制轉換)。MotionLayout
解決了這些問題。你可使用MotionLayout
作一樣的事,而且複用已存在的佈局文件來初始化狀態。首先須要爲組件建立一個MotionLayout
文件(motion_01_basic.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:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" tools:layout_editor_absoluteX="147dp" tools:layout_editor_absoluteY="230dp" /> </androidx.constraintlayout.motion.widget.MotionLayout>
文件佈局引用中了一個MotionScene
文件scene_01
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@layout/motion_01_cl_start" motion:constraintSetEnd="@layout/motion_01_cl_end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> </MotionScene>
scene_01
設置了默認的轉換,設置了開始和結束ConstrainSet
(motion_01_cl_start
和motion_01_cl_end
),並轉換爲設置了OnSwipe
處理。
在scene_01.xml
文件中咱們在Transition
中設置了OnSwipe
處理器。處理器經過匹配用戶的輸入事件控制轉換。
有一些屬性你須要瞭解:
touchAnchorId
:須要跟蹤的對象touchAnchorSide
:跟蹤手指的一側(右/左/上/下)dragDirection
:跟蹤手指運動的方向(dragRight / dragLeft / dragUp / dragDown將決定進度值的變化0-1)示例1展現瞭如何快速的建立一個MotionLayout
。,使用名單最終已了存在的佈局文件MotionLayout
還請當即獲取iTunes直接在MotionScene
文件中定義ConstraintSet
。這樣作有有如下好處:
ConstraintSet
MotionScene
中文件ConstraintSet
元素可使用的屬性不只全部遊戲經常使用的佈局屬性,位置除了狀語從句:邊距下面的屬性也。能夠在MotionLayout
中使用:
alpha visibility elevation rotation, rotation[X/Y] translation[X/Y/Z] scaleX/Y
讓咱們爲示例1從新建立一個新的自包含的MotionScene
。文件MotionLayout
文件除了引用了新的scene_02.xml
狀語從句:實例1中沒有區別:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/motionLayout" app:layoutDescription="@xml/scene_02" android:layout_width="match_parent" android:layout_height="match_parent"> <View android:id="@+id/button" android:background="@color/colorAccent" android:layout_width="64dp" android:layout_height="64dp" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
MotionScene
文件中有明顯的區別,Transition
的設置相同,可是咱們把Start
和結束直接定義在了XML文件中。和普通佈局文件相比主要的區別是咱們沒有指定具體的組件,而是把限定屬性寫在了Constraint
元素中。
<?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:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
只須要將瞭解ConstrainSet
是如何工做的,新的屬性將替換到關聯的組件上。只需將須要替換的屬性所有包含到Constraint
中。一般這會清除組件上的所用屬性並將新的屬性賦值到組件上。MotionLayout
的屬性
開發在中你可能會用到MotionLayout
的下列屬性:
app:layoutDescription=」reference」
指定MotionScene
XML文件app:applyMotionScene=」boolean」
是否應用MotionScene [default = true]app:showPaths=」boolean」
是否顯示路徑[default = false]。記得在發佈版本中關閉app:progress=」float」
指定轉換的進度[0-1]app:currentState=」reference」
指定一個ConstraintSet第一篇文章包含了MotionLayout
的基礎功能,你能夠在這裏查看源碼:https://github.com/googlesamples/android-ConstraintLayoutExamples
接下來的文章中咱們將包含更多的講解: