前言
MotionLayout?是一個在 ConstraintLayout 2.0 版本庫中新增的類,用于幫助 Android 開發(fā)者,在他們的 App 中,管理手勢以及動畫組件。
在這個系列文章我們將揭露,你如何添加這個庫到你的 App 里,以及如何運用 MotionLayout 的概念和特性來編寫程序。
在這個系列文章的 第一部分 我將揭露 MotionLayout 的基礎(chǔ):
MotionLayout 因何而生?
添加 ConstraintLayout 2.0 以及 MotionLayout 到你的工程
運用 MotionLayout
ConstraintSets
MotionScene
第一個例子:
OnSwipe handler
第二個例子:
MotionLayout 的屬性
小結(jié)
你也可以在 ?ConstraintLayout examples github repository 或者 這里 找到這些例子的源碼。
MotionLayout 因何而生?
Android 框架已經(jīng)提供了好幾種在 App 里添加動畫的方式:
下面將揭示 MotionLayout 和上面這些已有方案的不同。
MotionLayout,從它的名字就可以知道,首先它是一個布局控件,可以讓你安置你的元素。事實上它是 ConstraintLayout 的子類,進而在它的基礎(chǔ)上構(gòu)建了更強大的布局功能。
MotionLayout 作為 連接布局過度和復(fù)雜的手勢操作之間的橋梁 而生。你可以把它當(dāng)做介于屬性動畫框架、TransitionManager 和 CoordinatorLayout 之間的功能集合。
它可以讓你描述兩個布局的過渡動畫(類似 TransitionManager 那樣),而且還可以描述任何屬性動畫(不僅僅是布局屬性)。( 譯者注:這里的 “描述”,指的就是用 xml 表示 ) 此外,它內(nèi)置支持聯(lián)動(原文:seekable transitions),正如 CoordinatorLayout(它可以通過觸摸事件,和任意一點產(chǎn)生過渡動畫的聯(lián)動)。它支持觸摸操作和關(guān)鍵幀,可以讓開發(fā)者更容易根據(jù)自身需要自定義過渡動畫。
MotionLayout 是完全聲明式的。
除了上面提到的,MotionLayout 另一個關(guān)鍵的不同點在于它是完全聲明式的——你可以完全在 XML 中描述一個復(fù)雜的過渡動畫——無需任何代碼。如果你需要使用代碼表達移動手勢,現(xiàn)有的屬性動畫框架已經(jīng)提供了一個很好的方式實現(xiàn)它。(譯者注:言下之意,要用代碼實現(xiàn)動畫,那就用回屬性動畫吧)
MotionLayout 輔助工具
我們確實認(rèn)為,對聲明式移動規(guī)格的關(guān)注將簡化創(chuàng)建動畫,由此在 Android Studio 中提供了很好的圖像化工具。
由于我們正在開發(fā)這個工具,目前它是不可用的。一旦這個庫到了 stable 或者 beta 版本,這個工具就可以用了。

最后,作為 ConstraintLayout 2.0 的一部分,它可以作為一個支持庫,向下兼容到 API 級別 18,也就是JellyBean MR2(譯者注:就是我們通常說的 Android 4.3):這意味著它支持當(dāng)下 95% 的 Android 設(shè)備,可以查看 Android 系統(tǒng)實時市場占比 (譯者注:需科學(xué)上網(wǎng))

限制
MotionLayout 將僅僅為它的直接子視圖提供上述功能——這點正好和 TransitionManger 不一樣,TransitionManager 不僅還可以作用于內(nèi)嵌布局,還可以作用于 Activity 場景動畫。
何時使用它?
當(dāng)動畫 UI 元素和用戶產(chǎn)生交互時,我們就可以使用 MotionLayout
認(rèn)識清楚動畫是為什么目標(biāo)服務(wù)這是至關(guān)重要的——在你的應(yīng)用中,它不應(yīng)該是簡單的一個無端特效;它應(yīng)該能夠幫助用戶理解你的 App 正在做什么。Material Design 原則之 Understanding motion很好的介紹了這些理念。
有一個動畫類僅僅要處理演示預(yù)先的內(nèi)容,用戶不會或者不需要直接和內(nèi)容發(fā)生交互。一段視頻,一個動圖,或者以有限的方式比如動畫矢量或者 lottie 通常就屬于這一范疇。MotionLayout 不會特別的嘗試處理這類動畫(但是你當(dāng)然可以把他們包含在一個 MotionLayout 中)
添加 MotionLayout 到你的工程
簡單的通過添加 ConstraintLayout 2.0 到你的 Gradle 配置文件就可以了。
dependencies?{
????implementation?'com.android.support.constraint:constraint-layout:2.0.0-alpha1'
}運用 MotionLayout
MotionLayout 是 ConstraintLayout 的一個子類——這樣,你可以把它視為一個普通的布局。現(xiàn)有的 ConstraintLayout 轉(zhuǎn)換為 MotionLayout 是很容易的,只要像下面這樣替換類名:
改成

ConstraintLayout 和 MotionLayout 最主要的差異在于 XML 級別(_譯者注:使用 MotionLayout 就可以知道,在 xml 中它有一個 app:layoutDescription 屬性),MotionLayout 的子視圖布局屬性,并不一定要包含在布局文件中。
當(dāng)然,MotionLayout 通常子視圖布局屬性放到一個分開的 xml 文件中(這就是一個 MotionScene)然后引用它,而且定義在此處的子視圖布局屬性將優(yōu)先于布局文件的子視圖布局屬性。
這種方式,布局文件僅僅只包含自視圖和它們的屬性,而不包括它們的位置和運動。
ConstraintSets
ConstraintSet 大體的思想是,它們封裝所有的定位規(guī)則為你的布局;并且你能夠使用多個 ConstraintSet,然后你可以決定這一組規(guī)則立即運用于你的布局,而不需要重新創(chuàng)建你的視圖——僅僅只是改變它們的位置或者尺寸。
結(jié)合 TransitionManager(若無法科學(xué)上網(wǎng)可參考這里),這個提供了一個相對容易的方式使用 ConstraintLayout 創(chuàng)建動畫,正如上面視頻講述的那樣。
MotionLayout 本質(zhì)上是構(gòu)建于這些思想之上,同時擴展這些概念進一步發(fā)展。
MotionScene
如之前提到的那樣,和通常的布局控件不同,MotionLayout 的一些規(guī)格保存在另外一個 XML 文件中,它就是一個 MotionScene,存放于的 res/xml 資源目錄下。

一個 MotionScene 文件能夠包含所有下面指定的動畫:
使用 ConstraintSets
這些 ConstraintSets 之間的過度動畫
關(guān)鍵幀,觸摸操作,等等。
例如,讓我們嘗試實現(xiàn),使用你的手指能夠拖拽移動一個視圖,從屏幕的一端到另一端。

示例01:引用存在的布局
使用 ConstraintLayout,你將要創(chuàng)建兩個 ConstraintSet —— 一個是第一個位置(位于控件在屏幕的左邊),一個第二個位置(位于控件在屏幕的右邊)。
然后使用 TransitionManager 可以實現(xiàn)動畫。但是使用這種方式有一個問題,那就是,一旦過渡動畫開始,它就無法中斷。也就是說,你不能夠讓系統(tǒng)跳轉(zhuǎn)到過渡動畫指定的時間點——意味著你不能通過用戶輸入驅(qū)動過渡動畫。
譯者注:上面兩段翻譯本人閑寫得太啰嗦了,就粗略的翻譯了原文,作者的基本意圖就是引出下面使用 MotionLayout 比上面說的原有 ConstraintSet 方式更簡單有效,且使用類似 TransitionManger 的方式并不能夠?qū)崿F(xiàn)用戶驅(qū)動的動畫。
MotionLayout 就解決了所有的這些問題。下面展示你如何實現(xiàn)同樣的動畫,只要重用這些已經(jīng)存在的布局,來初始化兩個狀態(tài)。
首先,我們將創(chuàng)建一個 MotionLayout 文件為我們的控件:
????
注意,這個布局文件引用了一個 MotionScene 文件 —— scene_01
下面就是 scene_01:
???? ???????? ????
scene_01 指定默認(rèn)的過渡動畫,通過指定起始的 ConstraintSet(如上所示的:motion_01_cl_start 和 motion_01_cl_end) 。注意除此之外,我們還指定了一個 OnSwipe 來處理這個過渡動畫。
好!就這樣,你就能實現(xiàn)上面提到的動畫了。
OnSwipe handler
回到上面提到的 scene_01.xml 文件,我們指定了一個 OnSwipe 處理者,被包含在 Transition 里。這個處理者的角色是讓你驅(qū)動這個 Transition,通過匹配你的手指運動。

有些參數(shù)需要你來設(shè)置:
touchAnchorId: 我們需要追蹤的對象(這個例子中就是,@+id/button)
touchAnchorSide: 需要追蹤你手指運動的對象邊界(right/left/top/bottom)
dragDirection: 我們正追蹤的運動方向(dragRight / dragLeft / dragUp / dragDown 可以被設(shè)置通過定義進度值,從 0 到 1)





暫無評論,快來評論吧!