首頁 > 人文
Android:使用 Material Design 元件實現 Material 動效
由 高階網際網路專家 發表于 人文2023-01-03
簡介Material 動效目前包括四種過渡效果:容器轉換 (Container transform)共享軸 (Shared axis)淡入淡出 (Fade through)褪色 (Fade)我們已經在Android 平臺和AndroidX 過渡
過渡效果什麼意思
image
近期釋出的
Material 動效系統
是
MDC-Android 庫 (v 1。2。0)
的一部分,它將常用的過渡效果歸納為一組簡單的模式,提供更流暢更加容易理解的使用者體驗。Material 動效目前包括四種過渡效果:
容器轉換 (Container transform)
共享軸 (Shared axis)
淡入淡出 (Fade through)
褪色 (Fade)
我們已經在
Android 平臺
和
AndroidX 過渡系統
實現了以上過渡效果,以便在 Activity、Fragment 和 View 之間切換時輕鬆使用。
本文會介紹上面每種模式,並解釋如何將這些模式應用到您的應用中。我將會透過在示例應用
Reply
(一個簡單易用的郵件客戶端) 中實現對應的效果來說明每個步驟。Reply 應用的三個操作流程會使用到這些過渡動效:
開啟郵件
、
開啟搜尋頁面
、
切換信箱
。
如果您不滿足於上手介紹,更希望深入原始碼,請參閱
Material 動效 Codelab
,按步驟上手實踐這項技術,Codelab 也提供了在 Android 上使用這些過渡效果的其他資訊。
容器轉換: 開啟郵件
容器轉換是過渡的主角,容器轉換用在將一個元素轉換為另一個元素。什麼意思呢?例如示例的一個列表展開成為了詳情頁、
FAB
變形為工具欄,或
chip
擴充套件為了浮動的
卡片
。在每個場景中都有一個元件變換為另一個元件,並以動畫方式切換 “內部” 內容,同時維護一個共享的 “外部” 容器。使用容器變換,實現檢視間的動畫切換,可幫助增強它們之間的聯絡,並維持一個使用者的
導航上下文
。
在 Reply 示例中,我們在展示郵件列表的 Fragment (
HomeFragment
) 和郵件詳情 Fragment (
EmailFragment
) 間添加了容器轉換。如果您熟悉
Android 共享元素過渡
,它與容器轉換的設定非常相似。
首先,確定兩個共享元素的檢視,併為每一個檢視新增
過渡名稱
。第一個是單個郵件列表項的卡片,我們將使用
資料繫結
,來確保每一個列表項都有唯一的過渡名稱。
android:transitionName=“@{@string/email_card_transition_name(email。id)}”
第二個是
EmailFragment
內部的全屏卡片元件,這個元件可以設定一個靜態的過渡名稱,因為在檢視層級中只有這一個試圖。注意,兩個共享元素不需要使用相同的過渡名稱。
這兩個檢視會被我們的容器轉換使用。工作原理是: 它們都會被放在一個 drawable 內部,此 drawable 的邊界會被裁剪到 “容器” 中,而 “容器” 會將自己的形狀透過動畫從一個列表項轉換為詳情頁。在過渡過程中,透過傳入頁面在傳出螢幕上淡入,容器的內容 (列表項和詳情頁) 發生了交換。
現在我們已經標記了共享元素的檢視,接下來就可以建立目的地 Fragment 的
sharedElementEnterTransition
,並將其設定給一個
MaterialContainerTransform
的例項。預設情況下,從詳情頁面返回時,這個 sharedElementEnterTransition 會自動反轉並播放。
sharedElementEnterTransition = MaterialContainerTransform()。apply { // drawingViewId 是檢視的 id,在其上方,容器變換將在 z 軸空間進行 drawingViewId = R。id。nav_host_fragment duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong() // 由於我們也想將列表頁面透過動畫轉換出檢視,所以將 scrimColor 設定為透明 scrimColor = Color。TRANSPARENT setAllContainerColors(requireContext()。themeColor(R。attr。colorSurface))}
有關
引數的詳細資訊,請參閱
動效文件
當一封郵件被點選時,我們所有需要做的就是為 Fragment 事務提供開始檢視和結束檢視過渡名稱之間的對映。有了這些資訊,郵箱詳情 Fragment 共享元素過渡就可以使用我們提供的 MaterialContinaerTransform 找到並在兩個檢視之間進行動畫切換。
override fun onEmailClicked(cardView: View, email: Email) { exitTransition = MaterialElevationScale(false)。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong() } reenterTransition = MaterialElevationScale(true)。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong() } val emailCardDetailTransitionName = getString(R。string。email_card_detail_transition_name) val extras = FragmentNavigatorExtras(cardView to emailCardDetailTransitionName) val directions = HomeFragmentDirections。actionHomeFragmentToEmailFragment(email。id) findNavController()。navigate(directions, extras) }
在上面的程式碼片段中,我們也為傳出頁郵件 列表 Fragment 設定了
exit
和
reenter
的過渡效果。Material 元件提供了兩個過渡輔助:
Hold
和
MaterialElevationScale
,以平滑地為將要被替換的 Fragment 設定動畫。除了褪色 (Fade),MaterialElevationScale
還會在郵件列表頁退出時,對其進行縮放,並在重新進入郵件列表時縮放回來。Hold 僅僅是簡單地保留郵件列表。如果沒有設定退出時的過渡,我們的郵件列表會被立刻刪除並從檢視中消失。
如果我們在這個時候執行程式碼,從詳情頁導航返回到郵件列表頁,則返回過渡不會執行。這是因為當過渡開始時,郵件列表的介面卡還未被填充,過渡系統找不到與過渡名稱對應的兩個檢視。幸運的是,有兩個簡單方法可供我們使用: postponeEnterTransition 和 startPostponedEnterTransition。這兩個方法允許我們延遲過渡,直到我們知道我們的共享元素已經被佈局,並且可以被過渡系統發現。在 Reply 應用中,我們可以使用以下程式碼延遲過渡,直到我們確定 RecyclerView 介面卡已被填充,列表項已和過渡名稱繫結:
postponeEnterTransition()view。doOnPreDraw { startPostponedEnterTransition() }
在您自己的應用中,您可能需要嘗試這兩種方法,以根據您填充 UI 的方式和時間,來找到合適的時間開始延遲過渡。如果您發現您的返回動畫沒有執行,可能是在共享元素就緒之前開始了過渡。
接下來進入我們的搜尋頁面。
共享軸: 開啟搜尋頁面
共享軸模式用於有空間和導航關係的 UI 元素之間的過渡。在 Reply 應用中,開啟搜尋頁面會將使用者帶到郵件列表頂部的新頁面。為了介紹這個三維模型,我們可以在郵件列表 (
HomeFragment
) 和搜尋頁面 (
SearchFragment
) 之間使用共享 z 軸過渡。
共享軸過度會在操作兩個目標的同時建立最終的、編排過的過渡效果。這意味著 “成對” 的過渡會一起執行去建立連續的定向的動畫。對 Fragment 來說,這成對的過渡包括:
FragmentA 的
exitTransition
和 FragmentB 的
enterTransition
FragmentA 的
reenterTransition
returnTransition
MaterialSharedAxis
是實現了共享軸模式的類,它接收 forward 屬性來控制方向性的概念。在每一個過渡配對中,forward 必須被設定為相同的值,以便正確地協調這對動畫。
如需瞭解更多關於共享軸方向性的詳細資訊,請查閱
動效文件
。
在 Reply 應用中,這是我們為當前的 Fragment (
HomeFragment
) 建立退出和重入過渡的方法。
currentNavigationFragment?。apply { exitTransition = MaterialSharedAxis( MaterialSharedAxis。Z, /* forward= */ true )。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong() } reenterTransition = MaterialSharedAxis( MaterialSharedAxis。Z, /* forward= */ false )。apply { duration =resources。getInteger(R。integer。reply_motion_duration_large)。toLong() }}
在我們目的 fragment (
SearchFragment
) 中,我們建立進入和返回的過渡。
enterTransition = MaterialSharedAxis( MaterialSharedAxis。Z, /* forward= */ true)。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong()}returnTransition = MaterialSharedAxis( MaterialSharedAxis。Z, /* forward= */ false)。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong()}
注意: 當前 Fragment 的退出過渡和搜尋 Fragment 的進入過度使用相同的 forward 值 - true,當前 Fragment 的重入過渡和搜尋 Fragment 的返回過渡也是如此。
接下來,預設情況下,過度會在場景根層次結構內的所有子檢視上執行,這意味著一個共享軸過度會應用於郵件列表上的每一封郵件以及搜尋頁面的每一個子檢視。如果您想要 “傳播” 或者 “
錯開
” 動畫,這是一個非常好的功能,但是由於我們需要對每個 Fragment 的根作為整體進行動畫處理,我們需要在
郵件列表的 RecyclerView
和我們的
搜尋頁面的根 view group
設定
android:transitionGroup="true"
。
這樣,我們就在進出搜尋頁面時有了一個漂亮的共享 z 軸過渡!共享軸是一個非常靈活的過渡,可以應用於許多不同的場景,從頁面過渡到智慧回覆選擇,再到進入或者垂直的步驟流程。您已經配置好了設定,還可以嘗試使用
MaterialSharedAxis
的 axis 引數來了解其他軸動畫是什麼樣子。
淡入淡出: 切換郵箱
我們要介紹的最後一個模式是淡入淡出模式。淡入淡出可用於在沒有強關係的 UI 元素間過渡。當在兩個信箱之間過渡時,我們不希望使用者認為他們已經發送的郵件和他們的收件箱在導航上相關。由於每個信箱是一個頂級的目的地,淡入淡出是一個合適的選擇。在 Reply 應用中,我們將用不同的電子郵件列表 (帶有新引數的
HomeFragment
) 替換電子郵件列表 (
HomeFragment
)。
由於
MaterialFadeThrough
沒有方向性,所以設定起來更加簡單。我們只需要為傳出 Fragment 設定一個退出過渡,為傳入 Fragment 設定一個進入過渡。
currentNavigationFragment?。apply { exitTransition = MaterialFadeThrough()。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong() }}
enterTransition = MaterialFadeThrough()。apply { duration = resources。getInteger(R。integer。reply_motion_duration_large)。toLong()}}
在
上設定
的需求同樣適用於這裡,但是我們已經在共享軸配置的步驟中解決了這個問題。
以上就是淡入淡出過渡!您可以在自己專案有趣的地方來使用淡入淡出模式,比如: 底部導航欄的切換、列表項的交換,或替換一個工具欄選單。
一往無前!
本文簡要介紹了 Android 的 Material 動效系統。透過使用該系統所提供的模式,您可以在自定義動效時,做很多事情,使動效成為品牌體驗的一部分。本文我們看到了 Fragment 的過渡,但動效系統也可用於 Activity 甚至 View 間的過渡。檢視完整的
動效規範
文件,獲得更多啟發,以便思考哪些地方可提高您應用的核心體驗,或在一些小的地方增加額外的樂趣。
1
繼續學習,請檢視以下其他資源:
Material 動效開發文件
: 您可以在 Material Android 動效文件找到許多關於在 Activity 和 View 之間進行動畫的自定義選項和建議。
: 一個完整的分步的開發者教程,內容涉及如何在 Reply 應用中新增 Material 動效。
Android Google 雲盤
: 您可以在 Android Google 雲盤應用中看到正在執行的動效系統。點選資料夾、開啟搜尋、在底部導航間切換,這些都用到了 MDC-Android 的過渡效果。