再不遷移到Material Design Components 就out啦

翻譯自國外文檔加自己理解 原文

我們最近宣布了 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>

使用 AppCompatDesign 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.* 的主題,那麼就會把 ButtonAppCompatButton 來替換。現在把主題修改成 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

最新的組件完整列表以及使用文檔://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中已適當命名的現有屬性(例如colorPrimarycolorError
  • 新的屬性由MDC介紹(如colorSurfacecolorOnPrimary等)

MDC窗口小部件使用這些屬性來為其背景,文本,圖標等著色。要了解哪些小部件使用哪種顏色,需要檢查源程式碼中的默認小部件樣式。

AppCompat和框架中還存在一些顏色,但不再適用於此新系統。該Theme.MaterialComponents.*主題盡最大努力向後兼容他們,例如小部件,這些舊屬性。

<item name="colorAccent">?attr/colorSecondary</item>

但是,您應該考慮不推薦使用這些屬性。使用更合適的MDC屬性或逐步淘汰它們。

請參閱下面的顏色屬性映射表:

注意 AppCompat 中的顏色屬性就不要再使用了

AppCompat /框架顏色屬性 MDC-Android顏色屬性
colorPrimary colorPrimary
colorPrimaryDark colorPrimaryVariantandroid:statusBarColor明確指定)
不適用 colorOnPrimary
colorAccent colorSecondary
不適用 colorSecondaryVariant
不適用 colorOnSecondary
不適用 colorSurface
不適用 colorOnSurface
android:colorBackground android:colorBackground
不適用 colorOnBackground
colorError colorError
不適用 colorOnError
android:textColorPrimaryandroid:textColorSecondary等等。 N / A (建議將MDC設置為「 on」屬性或使用默認值)
colorControlNormalcolorControlHighlightcolorControlActivated N / A (「接通」或ATTRS使用默認偏好MDC) 注意:這些仍然被用來著色MaterialCheckBoxMaterialRadioButtonSwitchMaterialMaterialToolbar圖標

例子

<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/shapeAppearanceOverlaybackgroundTint 屬性來調整背景形狀和顏色。

以下情況需要單獨注意:

  • MaterialButton1.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 familysize 來自定義 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 或者更新的版本,可以直接使用 MaterialButtonandroid:background。需要注意的是要清空 backgroundTint,因為在默認的 style 中,backgroundTintcolorPrimary

<!-- Copyright 2020 Google LLC.
   SPDX-License-Identifier: Apache-2.0 -->
<Button
    android:background="@drawable/bg_button_gradient"
+    app:backgroundTint="@null"
    ... />
Tags: