翻譯自國外文件加自己理解 原文
我們最近宣佈了 Material Design Components(MDC)1.1.0
,這是一個庫更新,為您的 Android 應用程式帶來了 Material Theming
、新的元件、深色主題和其他令人興奮的功能。
MDC取代了設計支援庫。本指南將向您展示如何遷移程式碼庫,以便您可以使用新的屬性,樣式和小部件。
精簡的主題示例
本指南使用了精簡的應用程式來演示遷移過程。它使用AppCompat主題,設計支援庫中的小部件(包括具有自定義背景的按鈕)以及需要遷移的各種其他元素。我們將從使用傳統AppCompat模板的應用程式主題開始:
<style name="Theme.App" parent="Theme.AppCompat.*">
<item name="colorPrimary">@color/navy_700</item>
<item name="colorPrimaryDark">@color/navy_900</item>
<item name="colorAccent">@color/green_300</item>
</style>
使用 AppCompat
和 Design Support Library
的 APP
從 Support Library
遷移到 JetPack
在使用MDC之前,您需要從支援庫遷移到Android Jetpack。Jetpack使用新的androidx.*
名稱空間,並將以前的支援庫程式包拆分為單獨維護的語義版本化的庫,從而提供部分功能的新庫。MDC是使用AndroidX庫構建的,因此必須進行遷移。
要遷移到 AndroidX ,建議您遵循官方開發人員文件。 Android Studio中的 重構 > 遷移到 AndroidX 工具會將您的 Design Support Library
依賴重構成 MDC
。
更新到 MDC
首先要將build.gradle
依賴中
com.android.support:design:28.0.0
修改成 com.google.android.material:material:1.0.0
更改主題
需要將 app 的主題修改成 Material Components
主題的子類
<style name = "Theme.App" parent = "Theme.AppCompat.*"
修改成
<style name = "Theme.App" parent = "Theme.MaterialComponents.">
在 MDC
主題中有樣式和 AppCompat
一一對應,在大多數情況下,只需要簡單的將 AppCompat
替換成 MaterialComponents
就可以了
AppCompat theme | MDC-Android theme |
---|---|
Theme.AppCompat |
Theme.MaterialComponents |
Theme.AppCompat.NoActionBar |
Theme.MaterialComponents.NoActionBar |
Theme.AppCompat.Dialog.* |
Theme.MaterialComponents.Dialog.* |
Theme.AppCompat.DialogWhenLarge |
Theme.MaterialComponents.DialogWhenLarge |
Theme.AppCompat.Light |
Theme.MaterialComponents.Light |
Theme.AppCompat.Light.DarkActionBar |
Theme.MaterialComponents.Light.DarkActionBar |
Theme.AppCompat.Light.NoActionBar |
Theme.MaterialComponents.Light.NoActionBar |
Theme.AppCompat.Light.Dialog.* |
Theme.MaterialComponents.Light.Dialog.* |
Theme.AppCompat.Light.DialogWhenLarge |
Theme.MaterialComponents.Light.DialogWhenLarge |
Theme.AppCompat.DayNight |
Theme.MaterialComponents.DayNight |
Theme.AppCompat.DayNight.DarkActionBar |
Theme.MaterialComponents.DayNight.DarkActionBar |
Theme.AppCompat.DayNight.NoActionBar |
Theme.MaterialComponents.DayNight.NoActionBar |
Theme.AppCompat.DayNight.Dialog.* |
Theme.MaterialComponents.DayNight.Dialog.* |
Theme.AppCompat.DayNight.DialogWhenLarge |
Theme.MaterialComponents.DayNight.DialogWhenLarge |
AppCompat theme overlay | MDC-Android theme overlay |
---|---|
ThemeOverlay.AppCompat |
ThemeOverlay.MaterialComponents |
ThemeOverlay.AppCompat.Light |
ThemeOverlay.MaterialComponents.Light |
ThemeOverlay.AppCompat.Dark |
ThemeOverlay.MaterialComponents.Dark |
ThemeOverlay.AppCompat.*.ActionBar |
ThemeOverlay.MaterialComponents.*.ActionBar.* |
ThemeOverlay.AppCompat.Dialog.* |
ThemeOverlay.MaterialComponents.Dialog.* |
N/A | ThemeOverlay.MaterialComponents.*.BottomSheetDialog |
N/A | ThemeOverlay.MaterialComponents.MaterialAlertDialog.* |
N/A | ThemeOverlay.MaterialComponents.MaterialCalendar.* |
N/A | ThemeOverlay.MaterialComponents.Toolbar.* |
例子更新
Button 改變
從 Design
庫到 MDC
,樣式變成 Theme.MaterialComponents.*
後有了一些變化。拿 Button 來舉例,Button失去了自定義背景。現在 Button 有了一個綠色的強調色並且字型間的間距變大了。
那麼為什麼會這樣呢?我們先來看一下佈局
<Button
android:id="@+id/containedButton"
// 這是自定義的某種顏色的背景
android:background="@drawable/bg_button_gradient"
android:textColor="@android:color/white"
... />
<Button
android:id="@+id/textButton"
style=”?attr/borderlessButtonStyle”
... />
之所以出現這種情況是因為,在填充佈局的時候,會自動將我們佈局中的普通控制元件替換成 MDC
控制元件。
和 AppCompat 一樣,MDC 會在填充的時候用 MDC 等效的控制元件來替換某些原始控制元件。這樣就可以釋出新功能和錯誤修正了,而不必將所有宣告都換成新的型別。這是通過 MaterialComponentsViewInflater
來完成的,它屬於 AppCompatViewInflater
的子類。
對映關係:
Framework widget | AppCompat widget (replaced by AppCompatViewInflater ) |
MDC-Android widget (replaced by MaterialComponentsViewInflater ) |
---|---|---|
Button |
AppCompatButton |
MaterialButton |
CheckBox |
AppCompatCheckBox |
MaterialCheckBox |
RadioButton |
AppCompatRadioButton |
MaterialRadioButton |
TextView |
AppCompatTextView |
MaterialTextView |
AutoCompleteTextView |
AppCompatAutoCompleteTextView |
MaterialAutoCompleteTextView |
注意: 在 MDC 1.0.0
中只有 Button
控制元件被替換了。
我們例子中如果是 Theme.AppCompat.*
的主題,那麼就會把 Button
用 AppCompatButton
來替換。現在把主題修改成 Theme.MaterialComponents.*
,那麼就會把 Button
替換成 MaterialButton
,會有預設的 style
和 AppCompatButton
不同的是 MaterialButton
不支援自定義背景。到 1.2.0-alpha06
版本開始支援。使用 Shape
可以進行變通。下面章節會詳細介紹。
更新到 MDC 1.1.0
從 1.0.0 到 1.1.0 有了很多新變化:
- 完整的
Material Theming
Dark Theme
支援- Android 10 手勢導航支援
- 新元件:擴充套件 FAB、date picker、badges、toggle buttons
- 無障礙功能提升、bug 修復等等
implementation ‘com.google.android.material:material:1.1.0’
一些出乎意料的改變和普通問題
MDC 1.1.0
更改了一些預設的小部件樣式,以更好地符合“材料設計”準則。但是,升級後,您可能會注意到某些控制元件顏色和其他屬性的某些意外更改。
在上面的示例中,按鈕發生了變化、文字和圖示的顏色發生了變化。FAB 現在變成了藍綠色,並且文字欄位看起來完全不同。不用擔心。我們的當前主題中可能是丟失了一些重要的 MDC 屬性,同時有一些重要的 AppCompat 或者原有屬性(android:xxx)不再需要。下面我們通過一些常見的遷移方案來了解一下這些問題
文字欄位改變
在 MDC 中,文字欄位預設樣式發生了改變。改進版本是經過使用者調查研究的。
我們建議您使用這個版本,來提高可用性和可配置項性。但是我們意識到這可能並不適合您的品牌和設計系統。
要恢復為舊的文字欄位可以在佈局中新增樣式
<com.google.android.material.textfield.TextInputLayout
...
+ style="@style/Widget.Design.TextInputLayout">
...
</com.google.android.material.textfield.TextInputLayout>
或者你也可以在主題中給所有的文字設定預設樣式
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
+ <item name=”textInputStyle”>@style/Widget.App.TextInputLayout</item>
</style>
+<style name=”Widget.App.TextInputLayout” parent=”Widget.Design.TextInputLayout”>
+ <!-- Custom attrs -->
+</style>
更喜愛 MDC 樣式和控制元件
如上所述,先前支援庫的風格已經變成了 MDC 的一部分。在大多數的情況下,我們都可以通過 Widget.MaterialComponents.*
來替換 Widget.Design.*
樣式。並且還啟用了新的屬性,雖然可以不使用,但是我們建議還是採用新的 MDC 樣式!
建議使用 MDC
元件來替換AppCompat
或者 MaterialButton
(如果有的話)這些元件預設情況下使用更新後的材料設計指南。並且支援啟用 Material Theming
和其他功能。
下面這幾種情況應該考慮
- 在佈局中寫的控制元件如果有對應的 MDC 控制元件的話,直接使用 MDC 控制元件
- 任何的風格,預設風格和預設風格屬性應該改變成 MDC 版本
- 在程式設計中或者自定義類的父級類使用的任何控制元件都應該為 MDC 版本。
完整 控制元件和樣式對映表
MDC-Android widget (moved from Design Support Library) | Design Support Library default style | MDC-Android default style | Default style attr |
---|---|---|---|
AppBarLayout |
Widget.Design.AppBarLayout |
Widget.MaterialComponents.AppBarLayout.* |
appBarLayoutStyle |
BottomNavigationView |
Widget.Design.BottomNavigationView |
Widget.MaterialComponents.BottomNavigationView |
bottomNavigationStyle |
BottomSheetBehavior |
Widget.Design.BottomSheet.Modal |
Widget.MaterialComponents.BottomSheet.* |
bottomSheetStyle |
BottomSheetDialog BottomSheetDialogFragment |
Theme.Design.Light.BottomSheetDialog |
Theme.MaterialComponents.*.BottomSheetDialog ThemeOverlay.MaterialComponents.*.BottomSheetDialog |
bottomSheetDialogTheme |
CollapsingToolbarLayout |
Widget.Design.CollapsingToolbar |
N/A | N/A |
FloatingActionButton |
Widget.Design.FloatingActionButton |
Widget.MaterialComponents.FloatingActionButton |
floatingActionButtonStyle |
NavigationView |
Widget.Design.NavigationView |
Widget.MaterialComponents.NavigationView |
navigationViewStyle |
Snackbar |
Widget.Design.Snackbar |
Widget.MaterialComponents.Snackbar |
snackbarStyle |
TabLayout TabItem |
Widget.Design.TabLayout |
Widget.MaterialComponents.TabLayout |
tabStyle |
TextInputLayout TextInputEditText |
Widget.Design.TextInputLayout |
Widget.MaterialComponents.TextInputLayout.* |
textInputStyle |
AppCompat widget | AppCompat default style | AppCompat default style attr | MDC-Android widget | MDC-Android default style | MDC-Android default style attr |
---|---|---|---|---|---|
AlertDialog.Builder |
AlertDialog.AppCompat ThemeOverlay.AppCompat.Dialog.Alert |
alertDialogStyle alertDialogTheme |
MaterialAlertDialogBuilder |
MaterialAlertDialog.MaterialComponents ThemeOverlay.MaterialComponents.MaterialAlertDialog |
alertDialogStyle materialAlertDialogTheme |
AppCompatAutoCompleteTextView |
Widget.AppCompat.AutoCompleteTextView |
autoCompleteTextViewStyle |
MaterialAutoCompleteTextView |
Widget.MaterialComponents.AutoCompleteTextView.* ThemeOverlay.MaterialComponents.AutoCompleteTextView.* |
autoCompleteTextViewStyle |
AppCompatButton |
Widget.AppCompat.Button |
buttonStyle |
MaterialButton |
Widget.MaterialComponents.Button |
materialButtonStyle |
AppCompatCheckBox |
Widget.AppCompat.CompoundButton.CheckBox |
checkboxStyle |
MaterialCheckbox |
Widget.MaterialComponents.CompoundButton.CheckBox |
checkboxStyle |
AppCompatImageView |
N/A | N/A | ShapeableImageView |
Widget.MaterialComponents.ShapeableImageView |
N/A |
AppCompatRadioButton |
Widget.AppCompat.CompoundButton.RadioButton |
radioButtonStyle |
MaterialRadioButton |
Widget.MaterialComponents.CompoundButton.RadioButton |
radioButtonStyle |
AppCompatTextView |
Widget.AppCompat.TextView |
N/A | MaterialTextView |
Widget.MaterialComponents.TextView |
N/A |
CardView |
CardView |
cardViewStyle |
MaterialCardView |
Widget.MaterialComponents.CardView |
materialCardViewStyle |
PopupMenu |
Widget.AppCompat.PopupMenu.* |
popupMenuStyle |
N/A | Widget.MaterialComponents.PopupMenu.* |
popupMenuStyle |
SwitchCompat |
Widget.AppCompat.CompoundButton.Switch |
switchStyle |
SwitchMaterial |
Widget.MaterialComponents.CompoundButton.Switch |
switchStyle |
Toolbar |
Widget.AppCompat.Toolbar |
toolbarStyle |
MaterialToolbar |
Widget.MaterialComponents.Toolbar |
toolbarStyle |
最新的元件完整列表以及使用文件:https://material.io/develop/android/
示例更新
用 MDC 版本的元件來替換
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
-<androidx.cardview.widget.CardView
+<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
...>
...
-</androidx.cardview.widget.CardView>
+</com.google.android.material.card.MaterialCardView>
-<androidx.appcompat.widget.SwitchCompat
+<com.google.android.material.switch.SwitchMaterial
android:id="@+id/switch"
... />
顏色
MDC的顏色調色盤直接從 Material Design color system
中繪製。
由於MDC-Android,AppCompat和框架之間共享歷史記錄,因此,顏色屬性集包括以下內容:
- 框架中已適當命名的現有屬性(例如
android:colorBackground
) - AppCompat中已適當命名的現有屬性(例如
colorPrimary
和colorError
) - 新的屬性由MDC介紹(如
colorSurface
,colorOnPrimary
等)
MDC視窗小部件使用這些屬性來為其背景,文字,圖示等著色。要了解哪些小部件使用哪種顏色,需要檢查原始碼中的預設小部件樣式。
AppCompat和框架中還存在一些顏色,但不再適用於此新系統。該Theme.MaterialComponents.*
主題盡最大努力向後相容他們,例如小部件,這些舊屬性。
<item name="colorAccent">?attr/colorSecondary</item>
但是,您應該考慮不推薦使用這些屬性。使用更合適的MDC屬性或逐步淘汰它們。
請參閱下面的顏色屬性對映表:
注意 AppCompat 中的顏色屬性就不要再使用了
AppCompat /框架顏色屬性 | MDC-Android顏色屬性 |
---|---|
colorPrimary |
colorPrimary |
colorPrimaryDark |
colorPrimaryVariant (android:statusBarColor 明確指定) |
不適用 | colorOnPrimary |
colorAccent |
colorSecondary |
不適用 | colorSecondaryVariant |
不適用 | colorOnSecondary |
不適用 | colorSurface |
不適用 | colorOnSurface |
android:colorBackground |
android:colorBackground |
不適用 | colorOnBackground |
colorError |
colorError |
不適用 | colorOnError |
android:textColorPrimary ,android:textColorSecondary 等等。 |
N / A (建議將MDC設定為“ on”屬性或使用預設值) |
colorControlNormal ,colorControlHighlight ,colorControlActivated |
N / A (“接通”或ATTRS使用預設偏好MDC) 注意:這些仍然被用來著色MaterialCheckBox ,MaterialRadioButton ,SwitchMaterial 和MaterialToolbar 圖示。 |
例子
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="colorPrimary">@color/navy_700</item>
- <item name="colorPrimaryDark">@color/navy_900</item>
+ <item name="colorPrimaryVariant">@color/navy_900</item>
- <item name="colorAccent">@color/green_300</item>
+ <item name="colorSecondary">@color/green_300</item>
+ <item name=”colorSecondaryVariant”>@color/green_500</item>
+ <item name="android:statusBarColor">@color/navy_900</item>
</style>
@color
對於包含的按鈕文字顏色,我們還應該使用新的“ on”顏色屬性
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<Button
- android:textColor="@android:color/white"
+ android:textColor="?attr/colorOnPrimary"
... />
字型板式
新的 TextAppearance
樣式/屬性
MDC字型板式直接從Material Design型別系統中提取。表達的意思就是緊貼 Material Design 風格
引入了一組新的TextAppearance.MaterialComponents.*
樣式和相應的textAppearance*
主題屬性,它們替代了現有的AppCompat /框架樣式。
MDC小部件使用這些屬性來設定文字樣式。要知道哪些視窗小部件使用哪種型別板式,需要檢查原始碼中的預設視窗小部件樣式。
請參閱下面的完整型別樣式和屬性對映表: 13 種型別
AppCompat文字樣式 | MDC-Android文字樣式 | MDC-Android文字屬性 |
---|---|---|
TextAppearance.AppCompat.Display4 |
TextAppearance.MaterialComponents.Headline1 |
textAppearanceHeadline1 |
TextAppearance.AppCompat.Display3 |
TextAppearance.MaterialComponents.Headline2 |
textAppearanceHeadline2 |
TextAppearance.AppCompat.Display2 |
TextAppearance.MaterialComponents.Headline3 |
textAppearanceHeadline3 |
TextAppearance.AppCompat.Display1 |
TextAppearance.MaterialComponents.Headline4 |
textAppearanceHeadline4 |
TextAppearance.AppCompat.Headline |
TextAppearance.MaterialComponents.Headline5 |
textAppearanceHeadline5 |
TextAppearance.AppCompat.Title TextAppearance.AppCompat.Large |
TextAppearance.MaterialComponents.Headline6 |
textAppearanceHeadline6 |
TextAppearance.AppCompat.Subhead TextAppearance.AppCompat.Menu |
TextAppearance.MaterialComponents.Subtitle1 |
textAppearanceSubtitle1 |
TextAppearance.AppCompat.Small |
TextAppearance.MaterialComponents.Subtitle2 |
textAppearanceSubtitle2 |
TextAppearance.AppCompat.Body1 |
TextAppearance.MaterialComponents.Body1 |
textAppearanceBody1 |
TextAppearance.AppCompat.Body2 |
TextAppearance.MaterialComponents.Body2 |
textAppearanceBody2 |
TextAppearance.AppCompat.Button |
TextAppearance.MaterialComponents.Button |
textAppearanceButton |
TextAppearance.AppCompat.Caption |
TextAppearance.MaterialComponents.Caption |
textAppearanceCaption |
不適用 | TextAppearance.MaterialComponents.Overline |
textAppearanceOverline |
例子
<com.google.android.material.card.MaterialCardView
...>
...
<TextView
android:id=”@+id/headerText”
- android:textAppearance="@style/TextAppearance.AppCompat.Title"
+ android:textAppearance="?attr/textAppearanceHeadline6"
... />
<TextView
android:id=”@+id/subheadText”
android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="@style/TextAppearance.AppCompat.Body2"
+ android:textAppearance="?attr/textAppearanceBody2"
... />
<TextView
android:id=”@+id/supportingText”
android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="@style/TextAppearance.AppCompat.Body2"
+ android:textAppearance="?attr/textAppearanceBody2"
... />
</com.google.android.material.card.MaterialCardView>
自定義
我們還可以選擇在應用程式主題中覆蓋型別比例,以使用自定義字型系列,XML或通過Android Studio 下載字型:
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
+ <item name="textAppearanceHeadline6">@style/TextAppearance.App.Headline6</item>
+ <item name="textAppearanceBody2">@style/TextAppearance.App.Body2</item>
</style>
+<style name="TextAppearance.App.Headline6"
+ parent="TextAppearance.MaterialComponents.Headline6">
+ <item name="fontFamily">@font/roboto_mono_medium</item>
+</style>
+<style name="TextAppearance.App.Body2"
+ parent="TextAppearance.MaterialComponents.Body2">
+ <item name="fontFamily">@font/roboto_mono_regular</item>
+</style>
上面我們只是重寫了 13 種型別中的一種。如果你想要改變字型的話,建議也把剩餘的 12 修改了,以保持APP中字型的一致性。
Shape
ShapeAppearance
styles/attributes
Shape( Material Design shape system) 是用來處理 MDC 控制元件的邊角的一種方式,分成了小,中,大
這些合適的樣式屬性來自 ShapeAppearance.*
styles。包括:cornerFamily (兩種值:rounded cut) 。用 cornerSize
來表示尺寸
MDC小部件使用這些屬性來設定其背景樣式。要了解哪些視窗小部件適用於哪些形狀類別,需要檢查原始碼中的預設視窗小部件樣式。
控制元件背景
實現此功能的類為 MaterialShapeDrawable
. 預設情況下,所有的 MDC 控制元件都將此可繪製物件當做背景,我們也可以考慮將它用作自定義 View 的背景。它可以處理形狀主題、陰影、黑色主題等等。
因此。我們不建議使用 android:background
作為 MDC 控制元件的背景。因為它會覆蓋 MaterialShapeDrawable
。大多數的 MDC 控制元件的預設 style 都指定了 <item name="android:background">@null</item>
為了避免這種情況,應該使用 shapeApperance/shapeAppearanceOverlay
和 backgroundTint
屬性來調整背景形狀和顏色。
以下情況需要單獨注意:
MaterialButton
在1.2.0-alpha06
版本前忽略了android:background
如果你確實需要用這個屬性,考慮使用AppCompatButton
在你的佈局中。MaterialShapeDrawable
是不支援gradients
的。如果確實需要的話,最好用android:background
例子
在我們的示例中我們可以刪除一些由 shape theming
來處理的屬性。
<com.google.android.material.bottomnavigation.BottomNavigationView
- android:background="@android:color/white"
... />
<com.google.android.material.card.MaterialCardView
- app:cardCornerRadius="2dp"
...>
...
</com.google.android.material.card.MaterialCardView>
使用 corner family
和 size
來自定義 shape
我們可以選擇在應用主題中覆蓋形狀樣式來表達我們自己的品牌。
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
+ <item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.App.SmallComponent</item>
+ <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent</item>
+ <item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.App.LargeComponent</item>
</style>
+<style name="ShapeAppearance.App.SmallComponent"
+ parent="ShapeAppearance.MaterialComponents.SmallComponent">
+ <item name="cornerFamily">rounded</item>
+ <item name="cornerSize">8dp</item>
+</style>
+<style name="ShapeAppearance.App.MediumComponent"
+ parent="ShapeAppearance.MaterialComponents.MediumComponent">
+ <item name="cornerFamily">rounded</item>
+ <item name="cornerSize">12dp</item>
+</style>
+<style name="ShapeAppearance.App.LargeComponent"
+ parent="ShapeAppearance.MaterialComponents.LargeComponent">
+ <item name="cornerFamily">rounded</item>
+ <item name="cornerSize">16dp</item>
+</style>
使用 shape theming 的例子
恢復 Button 的自定義漸變背景
-<Button
+<androidx.appcompat.widget.AppCompatButton
android:background="@drawable/bg_button_gradient"
+ android:textAppearance="?attr/textAppearanceButton"
... />
如果使用的是 MDC 1.2.0-alpha-06
或者更新的版本,可以直接使用 MaterialButton
的 android:background
。需要注意的是要清空 backgroundTint
,因為在預設的 style 中,backgroundTint
為 colorPrimary
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<Button
android:background="@drawable/bg_button_gradient"
+ app:backgroundTint="@null"
... />