1. 簡介
Material Design 是打造搶眼數位產品的系統。產品團隊只要遵循一致的原則和元件組合,將樣式、品牌宣傳、互動和動畫一貫化,就能實現最大的設計潛力。
Material Design 元件 (MDC) 可協助開發人員實作質感設計。MDC 是由 Google 工程師和使用者體驗設計師團隊打造,提供數十種精美且功能豐富的 UI 元件,適用於 Android、iOS、網頁和 Flutter.material.io/develop |
Android 適用的 Material Design 動態系統為何?
Android 的 Material 動作系統是 MDC-Android 程式庫中的一系列轉換模式,可協助使用者瞭解及瀏覽應用程式,如 Material Design 指南所述。
主要的 Material 轉換模式如下:
- 容器轉換:在包含容器的 UI 元素之間轉換。將一個元素順暢轉換為另一個元素,以在兩個不同的 UI 元素之間建立明顯的連結。
- 共用軸:用於轉換有空間或導覽關係的 UI 元素。使用 x、y 或 z 軸的共用轉換來強化元素之間的關係。
- 淡入/淡出:轉換彼此關係不穩定的 UI 元素。會採用循序漸進的淡出和淡入,同時為傳入的元素縮放比例。
- 淡出:適用於在螢幕邊界內進入或離開的 UI 元素。
MDC-Android 程式庫為這些模式提供轉換類別,並以 AndroidX Transition Library (androidx.transition
) 和 Android Transition Framework (android.transition
) 為基礎:
AndroidX
- 「
com.google.android.material.transition
」套件提供 - 支援 API 級別 14 以上
- 支援 Fragment 和 View,但不支援 Activity 或 Windows
- 修正多個 API 級別中向後移植的錯誤和一致的行為
架構
- 「
com.google.android.material.transition.platform
」套件提供 - 支援 API 級別 21 以上
- 支援 Fragment、View、Activity 和 Windows
- 修正錯誤未向後移植,且在各 API 級別中可能會有不同的行為
在本程式碼研究室中,您將使用以 AndroidX 程式庫為基礎建構的 Material 轉換功能,這意味著您將專注於 Fragment 和 View。
建構項目
本程式碼研究室將引導您使用 Kotlin,將一些轉換內容建構成名為 Reply 的範例 Android 電子郵件應用程式,示範如何使用 MDC-Android 程式庫的轉換效果,自訂應用程式的外觀和風格。
系統會提供 Reply 應用程式的範例程式碼,而您要在應用程式中整合以下 Material 轉換,如以下程式碼研究室的 GIF 所示:
- Container 轉換:從電子郵件清單轉換至電子郵件詳細資料頁面
- 容器轉換會從懸浮動作按鈕 (FAB) 轉換為撰寫電子郵件頁面
- 共用 Z 軸從搜尋圖示轉換為搜尋檢視頁面
- 淡出在信箱頁面間轉換
- Container 轉換:從電子郵件地址方塊轉換為資訊卡檢視畫面
軟硬體需求
- 對 Android 開發作業和 Kotlin 有基本瞭解
- Android Studio (如果尚未安裝,請在這裡下載)
- Android 模擬器或裝置 (可透過 Android Studio 取得)
- 程式碼範例 (請參閱下一步)
你對建立 Android 應用程式的經驗程度為何?
2. 設定開發環境
啟動 Android Studio
開啟「Android Studio」時,畫面中會顯示標題為「Welcome to Android Studio」的視窗。不過,如果這是您第一次啟動 Android Studio,請按照 Android Studio 設定精靈步驟,輸入預設值。這個步驟可能需要幾分鐘的時間來下載和安裝必要檔案,因此您可以在後續部分中,繼續在背景執行。
方法 1:從 GitHub 複製入門程式碼研究室應用程式
如要從 GitHub 複製這個程式碼研究室,請執行下列指令:
git clone https://github.com/material-components/material-components-android-motion-codelab.git cd material-components-android-motion-codelab
方法 2: 下載 程式碼研究室應用程式的 ZIP 檔案
範例應用程式位於 material-components-android-motion-codelab-develop
目錄中。
在 Android Studio 中載入範例程式碼
- 設定精靈完成後,系統顯示「Welcome to Android Studio」視窗,請按一下「Open an existing Android Studio project」。
- 前往您安裝程式碼範例的目錄,然後選取範例目錄來開啟專案。
- 等待 Android Studio 建構並同步處理專案,如 Android Studio 視窗底部的活動指標所示。
- 此時,Android Studio 可能會引發部分建構錯誤,因為缺少 Android SDK 或建構工具 (如下所示)。請按照 Android Studio 中的指示安裝/更新這些套件,並同步處理專案。如果問題仍未解決,請按照指南的說明,使用 SDK Manager 更新工具。
驗證專案依附元件
專案需要 MDC-Android 程式庫的依附元件。您下載的程式碼範例中應該已列有這個依附元件,不過我們還是建議您查看設定以確保正確。
前往 app
模組的 build.gradle
檔案,確認 dependencies
區塊包含 MDC-Android 的依附元件:
implementation 'com.google.android.material:material:1.2.0'
執行範例應用程式
- 確認裝置選項左側的建構設定為
app
。 - 按下綠色的「Run」/「Play」按鈕,即可建構並執行應用程式。
- 在「Select Deployment Target」視窗中,如果可用裝置已列出「Android 裝置」,請跳至步驟 8。否則,請按一下「Create New Virtual Device」。
- 在「選取硬體」畫面中選取手機裝置 (例如「Pixel 3」),然後點選「下一步」。
- 在「System Image」畫面中選取最新的 Android 版本 (最好是最高 API 級別)。如果尚未安裝,請按一下畫面中顯示的「Download」(下載) 連結並完成下載。
- 點選「下一步」。
- 在「Android Virtual Device (AVD)」(Android 虛擬裝置 (AVD)) 畫面上維持原設定,然後按一下「Finish」(完成)。
- 從部署目標對話方塊中選取「Android 裝置」。
- 按一下 [確定]。
- Android Studio 會建構及部署應用程式,並自動在目標裝置上開啟應用程式。
大功告成!Reply 首頁的範例程式碼應在模擬器中執行。您應該會看到內含電子郵件清單的收件匣。
選用:放慢裝置動畫的速度
由於本程式碼研究室牽涉到快速、精美的轉場效果,因此建議您在實作過程中觀察裝置動畫,放慢速度,以便觀察一些更精確的轉場效果。您可以使用 adb
殼層指令或快速設定資訊方塊完成這項操作。請注意,這些拖慢裝置動畫的速度,會影響 Reply 應用程式以外裝置上的動畫。
方法 1:ADB Shell 指令
如要將裝置的動畫速度減慢 10 倍,可以在指令列中執行下列指令:
adb shell settings put global window_animation_scale 10
adb shell settings put global transition_animation_scale 10
adb shell settings put global animator_duration_scale 10
如要將裝置的動畫速度重設為正常,請執行下列指令:
adb shell settings put global window_animation_scale 1
adb shell settings put global transition_animation_scale 1
adb shell settings put global animator_duration_scale 1
方法 2:快速設定方塊
此外,如要設定「快速設定」資訊方塊,請在裝置上啟用開發人員設定 (如果尚未啟用):
- 開啟裝置的「設定」應用程式
- 向下捲動至底部,然後按一下「關於模擬裝置」
- 捲動至底部,然後快速按一下「版本號碼」直到啟用開發人員設定為止
接著,在裝置的「設定」中執行下列操作應用程式,如要啟用「快速設定」方塊:
- 按一下畫面頂端的搜尋圖示或搜尋列
- 輸入「Tiles」在搜尋欄位中
- 按一下「開發人員快速設定方塊」列
- 按一下「視窗動畫比例」開關
最後,在程式碼研究室中,從螢幕頂端下拉系統通知欄,然後使用 圖示,切換慢速和一般速度的動畫。
3. 熟悉範例應用程式的程式碼
我們來看看程式碼。我們提供了一個使用 Jetpack Navigation 元件程式庫的應用程式,可在多個不同的 Fragment 之間導覽,所有作業都在單一活動 MainActivity 中:
- HomeFragment:顯示電子郵件清單
- EmailFragment:顯示單封完整的電子郵件
- ComposeFragment:允許撰寫新電子郵件
- SearchFragment:顯示搜尋檢視畫面
navigation_graph.xml
首先,如要瞭解應用程式的導覽圖設定方式,請在 app -> src -> main -> res -> navigation
目錄中開啟 navigation_graph.xml
:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.materialstudies.reply.ui.home.HomeFragment"
android:label="HomeFragment">
<argument...>
<action
android:id="@+id/action_homeFragment_to_emailFragment"
app:destination="@id/emailFragment" />
</fragment>
<fragment
android:id="@+id/emailFragment"
android:name="com.materialstudies.reply.ui.email.EmailFragment"
android:label="EmailFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/composeFragment"
android:name="com.materialstudies.reply.ui.compose.ComposeFragment"
android:label="ComposeFragment">
<argument...>
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="com.materialstudies.reply.ui.search.SearchFragment"
android:label="SearchFragment" />
<action
android:id="@+id/action_global_homeFragment"
app:destination="@+id/homeFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/navigation_graph"
app:popUpToInclusive="true"/>
<action
android:id="@+id/action_global_composeFragment"
app:destination="@+id/composeFragment" />
<action
android:id="@+id/action_global_searchFragment"
app:destination="@+id/searchFragment" />
</navigation>
記下上述所有片段的呈現方式,而預設啟動片段是透過 app:startDestination="@id/homeFragment"
設為 HomeFragment
。這個片段目的地圖表的 XML 定義和動作,會告知產生的 Kotlin 導覽程式碼,您將在掛接轉換時遇到。
activity_main.xml
接下來,請查看 app -> src -> main -> res -> layout
目錄中的 activity_main.xml
版面配置。您會看見已透過上述導覽圖設定的 NavHostFragment
:
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph"/>
這個 NavHostFragment
會填滿螢幕,並處理應用程式中所有全螢幕片段的導覽變更。BottomAppBar
和其錨定 FloatingActionButton
(也在 activity_main.xml
中) 會配置在目前由 NavHostFragment
顯示的片段上方,因此會根據提供的範例應用程式程式碼的片段目的地顯示或隱藏。
此外,activity_main.xml
中的 BottomNavDrawerFragment
是底部導覽匣,內含一個選單,可用於瀏覽不同電子郵件信箱,並透過 BottomAppBar
回覆標誌按鈕 (有條件地顯示)
MainActivity.kt
最後,如要查看使用導覽動作的範例,請在 app -> src -> main -> java -> com.materialstudies.reply.ui
目錄中開啟 MainActivity.kt
。找出 navigateToSearch()
函式,如下所示:
private fun navigateToSearch() {
val directions = SearchFragmentDirections.actionGlobalSearchFragment()
findNavController(R.id.nav_host_fragment).navigate(directions)
}
這裡顯示如何在不自訂轉場效果的情況下,前往搜尋檢視頁面。在這個程式碼研究室中,您將深入探索 Reply 的 MainActivity 和四個主要片段,以設定 Material 轉換作業,並與整個應用程式中的各種導覽動作搭配使用。
現在您已熟悉範例程式碼,接下來要實作第一個轉換作業。
4. 新增從電子郵件清單到電子郵件詳細資料頁面的 Container Transform 轉換作業
首先,您將在點選電子郵件時新增轉場效果。針對這項導覽變更,容器轉換模式是非常實用的,因為其設計是為了在內含容器的 UI 元素之間轉換。這個模式可在兩個 UI 元素之間建立可見的連線。
新增任何程式碼之前,請先嘗試執行 Reply 應用程式,然後點選電子郵件。它應會執行簡單的跳轉,也就是以不轉換方式取代螢幕畫面:
請先在 email_item_layout.xml
的 MaterialCardView
上新增 transitionName
屬性,如以下程式碼片段所示:
email_item_layout.xml
android:transitionName="@{@string/email_card_transition_name(email.id)}"
轉換名稱採用含有參數的字串資源。您必須使用每個電子郵件的 ID,確保 EmailFragment
中的每個 transitionName
皆不重複。
現在您已設定電子郵件清單項目的轉換名稱,讓我們在電子郵件詳細資料版面配置中執行相同操作。在 fragment_email.xml
中,將 MaterialCardView
的 transitionName
設為下列字串資源:
fragment_email.xml
android:transitionName="@string/email_card_detail_transition_name"
在 HomeFragment.kt
中,將 onEmailClicked
中的程式碼替換為以下程式碼片段,從開始檢視畫面 (電子郵件清單項目) 和結束檢視畫面 (電子郵件詳細資料畫面) 建立對應關係:
HomeFragment.kt
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)
完成配電設定後,您就可以建立容器轉換。在 EmailFragment
onCreate
方法中加入下列程式碼片段,將 sharedElementEnterTransition
設為 MaterialContainerTransform
的新例項 (匯入 com.google.android.material.transition
版本而非 com.google.android.material.transition.platform
版本):
EmailFragment.kt
sharedElementEnterTransition = MaterialContainerTransform().apply {
drawingViewId = R.id.nav_host_fragment
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
setAllContainerColors(requireContext().themeColor(R.attr.colorSurface))
}
現在請嘗試重新執行應用程式。
一切都開始看起來很棒!當您點選電子郵件清單中的電子郵件時,容器轉換應將清單項目展開為全螢幕詳細資料頁面。不過請注意,按下「返回」鍵並不會將電子郵件收合回清單。此外,電子郵件清單會在轉換開始時立即消失,顯示灰色視窗背景。我們還沒結束
如要修正傳回轉換,請在 HomeFragment.kt
的 onViewCreated
方法中加入以下兩行:
HomeFragment.kt
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
請嘗試重新執行應用程式。開啟電子郵件後按下返回按鈕,即可將電子郵件收合回清單中。太好了!我們繼續改善動畫。
電子郵件清單消失的問題在於,使用 Navigation 元件前往新的 Fragment 時,系統會立即移除目前的 Fragment,並替換成新的傳入 Fragment。如要讓電子郵件名單在取代後仍繼續顯示,您可以為 HomeFragment
新增退出轉場效果。
將下列程式碼片段新增至 HomeFragment
onEmailClicked
方法,讓電子郵件清單在退出時經過細看,並在重新輸入時移回:
HomeFragment.kt
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()
}
接下來,為確保 MaterialElevationScale
轉換效果套用至整個主畫面,而非套用至階層中的每個個別檢視畫面,請將 fragment_home.xml
中的 RecyclerView
標示為轉換群組。
fragment_home.xml
android:transitionGroup="true"
在這個階段,您應該會有一個正常運作的容器轉換。按一下電子郵件,清單項目會展開為詳細資料畫面,並捲動電子郵件清單。按下返回按鈕,即可將電子郵件詳細資料畫面收合回清單項目,同時放大電子郵件清單。
5. 新增從懸浮動作按鈕 (FAB) 轉換為撰寫電子郵件頁面的 Container Transform 轉換作業
讓我們繼續使用容器轉換,並將「懸浮動作」按鈕的轉場效果新增至 ComposeFragment
,將 FAB 展開為要由使用者撰寫的新電子郵件。首先,請重新執行應用程式,然後點選懸浮動作按鈕 (FAB),確認啟動電子郵件撰寫畫面時不會發生轉換。
雖然我們使用相同的轉換類別,但由於我們 FAB 位於 MainActivity
,且 ComposeFragment
位於 MainActivity
導覽主機容器中,因此我們設定這個執行個體的方式會有所不同。
在 ComposeFragment.kt
中,將下列程式碼片段新增至 onViewCreated
方法,並務必匯入 Slide
的 androidx.transition
版本。
ComposeFragment.kt
enterTransition = MaterialContainerTransform().apply {
startView = requireActivity().findViewById(R.id.fab)
endView = emailCardView
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
scrimColor = Color.TRANSPARENT
containerColor = requireContext().themeColor(R.attr.colorSurface)
startContainerColor = requireContext().themeColor(R.attr.colorSecondary)
endContainerColor = requireContext().themeColor(R.attr.colorSurface)
}
returnTransition = Slide().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_medium).toLong()
addTarget(R.id.email_card_view)
}
除了用來設定先前容器轉換的參數外,startView
和 endView
也是在這裡手動設定。您可以視需要手動指定這些檢視畫面,而不使用 transitionName
屬性讓 Android 轉換系統知道應轉換哪些檢視畫面。
現在,請重新執行應用程式。您應該會看到懸浮動作按鈕 (FAB) 正在轉換為撰寫畫面 (請參閱這個步驟結尾的 GIF)。
與上一個步驟類似,您需要新增轉場效果至 HomeFragment
,以免該轉場在移除並替換為 ComposeFragment
後消失。
將下列程式碼片段複製到 MainActivity
中的 navigateToCompose
方法,再呼叫 NavController
navigate
。
MainActivity.kt
currentNavigationFragment?.apply {
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()
}
}
這個步驟就完成了!建議您從懸浮動作按鈕 (FAB) 轉換為 Compose 畫面,如下所示:
6. 新增分享的 Z 軸從搜尋圖示到搜尋檢視頁面
在這個步驟中,我們要新增轉場效果:從搜尋圖示轉換至全螢幕搜尋檢視畫面。由於這次導覽變更並未牽涉到永久的容器,因此我們可以使用共用的 Z 軸轉場來強化兩個畫面之間的空間關係,並指定應用程式階層中向上的一層。
如要新增其他程式碼,請先執行應用程式,然後輕觸畫面右下角的搜尋圖示。這應該會出現搜尋檢視畫面,而不顯示任何轉場效果。
首先,請在 MainActivity
中找出 navigateToSearch
方法,在 NavController
navigate
方法呼叫之前加入下列程式碼片段,設定目前片段的結束事件,並重新輸入 MaterialSharedAxis
Z 軸轉場效果。
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
接著,將下列程式碼片段新增至 SearchFragment
中的 onCreate
方法,即可設定進入及傳回 MaterialSharedAxis
轉場效果。
SearchFragment.kt
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
最後,為確保 MaterialSharedAxis
轉換作業套用至整個搜尋畫面,而非套用至階層中的每個個別檢視畫面,請將 fragment_search.xml
中的 LinearLayout
標示為轉換群組。
fragment_search.xml
android:transitionGroup="true"
大功告成!現在請嘗試重新執行應用程式,然後輕觸搜尋圖示。主畫面和搜尋畫面應同時沿著 Z 軸深度淡出和縮放,讓兩個畫面之間能流暢地相輔相成。
7. 在信箱頁面之間新增淡入/淡出轉場效果
在這個步驟中,我們會在不同信箱之間新增轉換作業。由於我們不想強調空間或階層關係,因此我們會使用淡入效果來執行簡單的「切換」作業電子郵件清單。
新增任何程式碼之前,請先嘗試執行應用程式、輕觸底部應用程式列中的「Reply」標誌,然後切換信箱。電子郵件清單應在不經過轉換的情況下變更。
首先,請在 MainActivity
中找出 navigateToHome
方法,然後在 NavController
navigate
方法呼叫之前加入下列程式碼片段,設定目前片段的結束 MaterialFadeThrough
轉換。
MainActivity.kt
currentNavigationFragment?.apply {
exitTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
}
接著開啟 HomeFragment
。在 onCreate
中,將片段的 enterTransition
設為 MaterialFadeThrough
的新例項。
HomeFragment.kt
enterTransition = MaterialFadeThrough().apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
重新執行應用程式。開啟底部導覽匣並變更信箱時,新清單上的電子郵件清單應淡出並縮小,同時顯示在新清單淡出及縮放。太棒了!
8. 新增從電子郵件地址方塊轉換至資訊卡檢視的 Container Transform 轉換作業
在這個步驟中,您將新增轉場效果,可將方塊轉換為彈出式資訊卡。容器轉換在這裡是用來告知使用者,在彈出式視窗中執行的操作會影響該彈出式視窗的來源方塊。
新增任何程式碼之前,請執行 Reply 應用程式,然後依序點選電子郵件中的「回覆」懸浮動作按鈕 (FAB),然後試著點選收件者的聯絡人方塊。方塊應該會立即消失,並顯示包含該聯絡人電子郵件地址的資訊卡,且資訊卡應當顯示,但不顯示動畫。
你將透過 ComposeFragment
進行這個步驟。已新增至 ComposeFragment
版面配置的收件者方塊 (預設為顯示) 和收件者資訊卡 (預設為隱藏)。收件者方塊和這張資訊卡是您在兩者之間建立容器轉換的兩個檢視畫面。
首先,請開啟 ComposeFragment
並找到 expandChip
方法。使用者點選提供的 chip
時,就會呼叫此方法。在交換 recipientCardView
和 chip
瀏覽權限的各行上方加入下列程式碼片段,即可觸發透過 beginDelayedTransition
登錄的容器轉換。
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = chip
endView = binding.recipientCardView
scrimColor = Color.TRANSPARENT
endElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(binding.recipientCardView)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
如果現在執行應用程式,方塊應轉換成收件者的電子郵件地址資訊卡。接下來,請設定返回轉場效果,將資訊卡收合回方塊。
在 ComposeFragment
的 collapseChip
方法中加入下列程式碼片段,將資訊卡收合回方塊。
ComposeFragment.kt
val transform = MaterialContainerTransform().apply {
startView = binding.recipientCardView
endView = chip
scrimColor = Color.TRANSPARENT
startElevation = requireContext().resources.getDimension(
R.dimen.email_recipient_card_popup_elevation_compat
)
addTarget(chip)
}
TransitionManager.beginDelayedTransition(binding.composeConstraintLayout, transform)
重新執行應用程式。使用者點選方塊後,方塊應展開成資訊卡,點選資訊卡時,資訊卡則會收合回方塊。太棒了!
9. 全部完成
MDC-Android 程式庫使用不到 100 行的 Kotlin 程式碼和一些基本 XML 標記,可協助您在符合 Material Design 指南的現有應用程式中建立美觀的轉場效果,而且所有 Android 裝置上的外觀和行為也都一致。
後續步驟
如要進一步瞭解 Material 動態效果系統,請務必查看規格和完整的開發人員說明文件,嘗試在應用程式中新增一些 Material 轉場效果!
感謝你試用 Material Design。希望您喜歡本程式碼研究室!