本文是對Introduction to MotionLayout的翻譯,本身可能翻譯的有點很差,歡迎你們批評指正。侵權刪。php
MotionLayout是一個在ConstraintLayout2.0版本庫的時候添加的一個新的類,能夠幫助開發者處理一些動畫。android
Android framework已經提供瞭如此多的方式來幫咱們在應用中添加動畫,app
那麼MotionLayout與它們有什麼不一樣的地方?ide
當想要對與用戶有直接交互的UI元素作動畫時。佈局
什麼是對與用戶有着直接交互的UI元素?就是用戶的點擊,滑動等動做。gradle
dependencies {
implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha2'
}
複製代碼
MotionLayout是ConstraintLayout的子類。要想已有的ConstraintLayout變成MotionLayout只須要在具體的xml中,將:動畫
<android.support.constraint.ConstraintLayout .../>
複製代碼
改爲google
<android.support.constraint.motion.MotionLayout .../>
複製代碼
MotionLayout動畫的具體的描述文件並無包含在定義MotionLayout的layout文件中,而是定義在了一個單獨的xml文件(一個MotionScene
文件)。spa
就如同以前所說,描述MotionLayout的動畫的具體信息被定義在了一個單獨的xml文件,MotionScene,一般存儲在res/xml
目錄下翻譯
如圖所述,一個MotionScene一般包含以下的內容
就像下面的例子,咱們經過使用手指拖動一個簡單的view從屏幕的一端滑動至另外一端,如何作到呢?
一個指向初始的layout(view在屏幕左端),一個指向結束的layout(view在屏幕的右端),咱們須要定義兩個layout
view在左端的layout:
<?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>
複製代碼
view在右端的layout:
<?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>
複製代碼
而後定義一個MotionLayout文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.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" />
</android.support.constraint.motion.MotionLayout>
複製代碼
注意這個layout文件指向了一個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
經過指定開始和結束的ConstraintSet(motion_01_cl_start
和motion_01_cl_end
,規定了過渡動畫。注意,咱們指定了OnSwipe
標籤在transition中
在scene_01.xml
文件中,咱們指定了一個OnSwipe
標籤,在一個Transition
標籤中,做用是依據咱們的手指的動做,來讓動畫發生。
OnSwipe
的具體的各類屬性
touchAnchorId
:咱們想要作動畫的object對象,(這裏是@+id/button
)
touchAnchorSide
:object的邊,(right/left/top/bottom)
dragDirection
:咱們所想要追蹤的手指動做的方向(dragRight/dragLeft/dragUp/dragDown)
第一種實現方式重用了layout(基於ConstraintLayout)
MotionLayout一樣支持直接在MotionScene中定義ConstraintSets,這帶來了以下優點:
讓咱們將ConstraintSets直接定義在MotionScene中,達到和實現1同樣的效果
咱們定義一個與實現1中同樣的MotionLayout文件,只須要引用scene_02.xml
<?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>
複製代碼
在scene_02.xml
中,Transition
標籤內部是一致的,區別在於咱們直接將start
和end
的Constrait定義在了文件中。並由一個ConstraintSet
標籤包含着。
<?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>
複製代碼
在Constraint標籤中除了能夠定義元素的位置以外,還能夠定義一些其餘的屬性,MotionLayout將自動地爲這些屬性生成中間的過渡狀態,也就是插值。
alpha
visibility
elevation
rotation,rotation[x / y]
translation[x / y / z]
scaleX / Y
相似於下面的形式
<Constraint android:id="@id/content" android:layout_width="0dp" android:layout_height="match_parent" motion:layout_constraintWidth_default="percent" motion:layout_constraintWidth_percent="1" android:scaleX="0.8" android:scaleY="0.8" motion:layout_constraintLeft_toRightOf="@+id/button" motion:layout_constraintTop_toTopOf="parent"/>
複製代碼
MotionLayout提供了一些屬性
app:layoutDescription="reference"
,指向一個MotionScene XML文件
app:applyMotionScene="boolean"
是否使用MotionScene,默認爲true
app:showPaths="boolean"
展現motion 路徑,默認爲false,app正式發佈的時候要記得關閉
app:pregress="float"
明確指定中間進度,區間在0到1
app:currentState="reference"
強制一個特定的ConstraintSet
這篇文章只是MotionLayout的基礎的功能的一個介紹,MotionLayout可以實現的功能遠不止如此。