使用 Material 主題 (Theming) 自定義 Material 組件,目的是讓組件觀感與品牌保持一致。Material 主題包括 顏色、字體 和 形狀 參數(shù),您可以對這些參數(shù)進行調整來獲得近乎無限的組件變體,同時保持其核心結構和易用性。
自版本 1.1.0 開始,您可以在 Android 中使用 Material 組件 (Material Design Components, MDC) 庫 來實現(xiàn) Material 主題。如果您要從設計支持庫 (Design Support Library) 或 MDC 1.0.0 遷移至新版 MDC,請參閱我們提供的遷移指南—— 遷移至 Android Material 組件。
本文將重點討論如何實現(xiàn)字體樣式主題。
字體樣式屬性
Material Design 提供 13 種適用于應用中所有文字的 "樣式 (styles)",每一種樣式都有一個設計術語 (例如 "Body 1") 以及對應的字體樣式屬性,您可以在應用主題中覆寫這些屬性 (例如 textAppearanceBody1)。每一種樣式的屬性都有默認的 "基準" 值 (文字尺寸、字符間距、大小寫等)。
Material 組件使用這些字體樣式屬性來為組件的文本元素設置樣式,這些組件通常繼承自 TextView 或組合了一個或多個 TextView。
字體樣式屬性在布局和組件樣式中的應用如下:
android:textAppearance=”?attr/textAppearanceBody1”
關于字體樣式屬性的使用,以及多種樣式化方案同時使用時被應用的優(yōu)先級順序,如需了解更多,請查閱 Nick Butcher 的文章 —— "如何實現(xiàn)文字外觀"。
在 MDC 主題中,這些屬性會映射到樣式上,例如:
<style name=”Theme.MaterialComponents.*” parent="...">
...
<item name=”textAppearanceBody1”>
@style/TextAppearance.MaterialComponents.Body1
</item>
<style />
您也許在 AppCompat 或平臺中已經(jīng)接觸過 TextAppearance
樣式,我們將在本文的 字體樣式資源 部分進行詳細介紹。其對應的屬性是 MDC 的新增內容,使您能夠根據(jù)不同主題變換不同文字樣式。
選擇字體樣式
厘清應該選擇使用何種字體樣式以及其中的屬性值也許是設計師的責任,也許它們源自您的品牌。然而,了解每一種樣式的作用及其使用場景是非常有用的:
textAppearanceHeadline* 樣式應用于標題
textAppearanceSubtitle* 樣式應用于副標題
textAppearanceBody* 樣式應用于多行文本正文
textAppearanceButton 樣式應用于按鈕,但是同樣也適用于其他組件的部分內容,例如 Tab 和彈窗中的操作
textAppearanceCaption 樣式應用于小號文本,例如輸入框的提示和錯誤信息
textAppearanceOverline 樣式也應用于小號文本,但是它具有大寫英文字母和更大的字符間距,因此更適合于小標題和 Label,例如日期選擇器的標題
字體樣式工具
Material Design 提供了一個實用工具,它可以預覽字型縮放,集成了 Google Font,并且可以導出代碼。請查閱 Material Design 字體樣式指南 中的 "字型縮放生成器"。
據(jù)。請查閱由 Rod Sheeter 撰寫的 "助力 Android 開發(fā)者實現(xiàn)更好的排版指南" 來了解關于字體預加載更詳細的指南和進一步的優(yōu)化。
我們通常推薦使用可下載字體,因為它們會借助共享字體提供程序的緩存來減小應用包體積。但是,可下載字體目前僅可使用 Google Font 上的字體。如果您的應用需要使用已購買的字體或專用字體,請使用 XML 字體。
同樣值得注意的是,從 API 26 開始,Android 支持使用可變字體。請查閱 Rebecca Franks 的文章 —— "Android O 上的可變字體??" 以了解更多信息。
TextAppearance 樣式
TextAppearance
樣式可以被當成是 Android 上的 Material Design 字體樣式。對于自定義的樣式,我們推薦兩種方法來幫您實現(xiàn)關注點分離,并為應用中的字體樣式主題值創(chuàng)建單一的數(shù)據(jù)來源:
將所有
TextAppearance
樣式存放在同一個 res/values/type.xml 文件中使用 MDC
TextAppearance
作為父樣式,并遵守相同的命名規(guī)則
這些樣式中可使用的屬性和值與 TextView
支持的屬性和值一致:
fontFamily
定義字族,通常使用 @font/ 資源引用 XML 或可下載字體android:textSize
定義文本的大小,通常是一個 sp 尺寸android:textColor
定義文本的顏色android:letterSpacing
定義字符的間距a
ndroid:textAllCaps
定義是否開啟文本大寫,是一個布爾值android:textFontWeight
定義字體的粗細,用于從字族中選擇最接近的匹配項,但是只在 API 28 及以上的版本中可用。也可以使用android:textStyle
來設置效果,例如bold
(粗體) 和italic
(斜體)
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!-- In res/values/type.xml -->
<style name="TextAppearance.App.Headline6" parent="TextAppearance.MaterialComponents.Headline6">
<item name="fontFamily">@font/roboto_mono</item>
...
</style>
<style name="TextAppearance.App.Body2" parent="TextAppearance.MaterialComponents.Body2">
<item name="fontFamily">@font/roboto_mono</item>
<item name="android:textSize">14sp</item>
...
</style>
<style name="TextAppearance.App.Button" parent="TextAppearance.MaterialComponents.Button">
<item name="fontFamily">@font/roboto_mono</item>
<item name="android:textAllCaps">false</item>
...
</style>
計算字符間距
字符間距在 Android 中使用的測量單位 (em) 與設計工具如 Sketch 使用的測量單位 (tracking) 不同。Material Design 排版指南 提供了一個相對簡單的方程式將 tracking 值轉換為合適的 em 值:
(Sketch 中的 tracking 值 / 字體尺寸 sp) = 字符間距
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!-- (0.25 tracking / 14sp font size) = 0.0178571429 em -->
<style name="TextAppearance.App.Body2" parent="TextAppearance.MaterialComponents.Body2">
<item name="fontFamily">@font/roboto_mono</item>
<item name="android:textSize">14sp</item>
+ <item name="android:letterSpacing">0.0178571429</item>
...
</style>
MaterialTextView 和行高
系統(tǒng)版本的 TextView 在 API 28 中添加了 android:lineHeight 屬性。MDC 通過 MaterialTextView 類為該屬性提供了向下兼容能力。您不需要直接在布局中使用該類,因為 MaterialComponentsViewInflater 會自動將 <TextView>
替換為 MaterialTextView
。
您可以在多種場景中使用 lineHeight
:
- 作為一個 item 被包含于
TextAppearance
樣式中 (使用android:textAppearance="..."
應用該樣式) - 作為一個 item 被包含于父樣式為
Widget.MaterialComponents.TextView
的組件樣式中 (使用style="..."
應用該樣式) - 直接應用于布局中的
<TextView>
注意事項
- 您不必覆寫全部字體樣式。但是請注意,默認的 MDC 樣式使用系統(tǒng)字體 (通常是 Roboto)。請確保檢查了您的組件和
TextView
使用的是哪種字體樣式。 - 雖然
TextAppearance
支持設置android:textColor
,但 MDC 偏向于在主要組件樣式中聲明該屬性以保證遵循關注點分離原則,例如:
<style name=”Widget.MaterialComponents.*” parent=”...”>
...
<!-- Color -->
<item name=”android:textColor”>?attr/colorOnSurface</item>
<!-- Type -->
<item name=”android:textAppearance”>
?attr/textAppearanceBody1
</item>
</style>
額外的字體樣式
如果您的設計系統(tǒng)需要的字體樣式在 Material 主題提供的 13 種樣式外,慶幸的是在 Android 中實現(xiàn)起來相對簡單,您可以通過如下方式聲明樣式屬性:
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!-- In res/values/attrs.xml -->
<attr name="textAppearanceCustom" format="reference" />
<!-- In res/values/type.xml -->
<style name="TextAppearance.App.Custom" parent="TextAppearance.MaterialComponents.*">
...
</style>
<!-- In res/values/themes.xml -->
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="textAppearanceCustom">@style/TextAppearance.App.Custom</item>
</style>
覆寫應用主題中的字體樣式
接下來,我們來討論如何通過覆寫相應屬性,將您選擇的字體樣式添加到應用主題中。
首先,我們建議您設置主題以便優(yōu)雅地處理淺色和深色調色板,同時也可以減少與基本主題的重復。如需了解更多此話題相關信息,請參閱 Chris Banes 撰寫的 深色主題文章,以及他和 Nick Butcher 的演講 —— "使用樣式開發(fā)主題"。
設置完成后,在您應用的基本主題中覆寫您想要改變的字體樣式屬性:
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!-- In res/values/themes.xml -->
<style name="Theme.App.Base" parent="Theme.MaterialComponents.*">
...
<item name="textAppearanceHeadline6">
@style/TextAppearance.App.Headline6
</item>
<item name="textAppearanceBody2">
@style/TextAppearance.App.Body2
</item>
<item name="textAppearanceButton">
@style/TextAppearance.App.Button
</item>
<!-- Using default values for textAppearanceSubtitle1, textAppearanceCaption, etc. -->
</style>
Material 組件會響應主題級的字體樣式覆寫:
MDC 組件中的字體樣式
您已經(jīng)知道 MDC 組件會響應主題級的樣式覆寫。但是您如何知道諸如某個按鈕使用 textAppearanceButton 作為它文本標簽的樣式呢?讓我們來看看以下幾種方式。
構建 Material 主題
構建 Material 主題 是一個可交互的 Android 項目,您可以通過它修改顏色、字體樣式、形狀的值來創(chuàng)建您自己的 Material 主題。它還包含了所有主題參數(shù)和組件的目錄。您可以按如下步驟來確定哪些組件會響應主題字體樣式屬性的改變:
克隆 該項目 并在 Android Studio 中運行它
調整 res/values/type.xml 和 res/values/themes.xml 文件中的值
重新運行應用并觀察視覺變化
MDC 開發(fā)者文檔
MDC 開發(fā)者文檔已于最近更新。在本次更新中,我們加入了屬性表,涵蓋了開發(fā)庫中所使用的設計術語和屬性默認值。例如下面是更新的 按鈕文檔 的 "Anatomy and key properties" (詳解和關鍵屬性) 部分。
源碼
檢索 MDC 源碼可以說是最可靠的方式。MDC 使用默認樣式來實現(xiàn) Material 主題,因此可以查看這些樣式以及任何可樣式化屬性和 Java 文件。例如,查閱 MaterialButton 的 樣式、屬性 和 Java 文件。
自定義 View 中的字體樣式
您的應用中也許會引入您自己開發(fā)或現(xiàn)有庫中的自定義組件。當它們與標準 MDC 組件共同使用時,有必要保證它們能響應 Material 主題變化。以下是為自定義組件支持樣式主題化的注意事項。
在 <declare-styleable> 和默認樣式中使用 MDC 屬性
當自定義 View 使用了<declare-styleable>
標簽時將可被樣式化。復用 MDC 中的 attr name 有利于保持統(tǒng)一。使用 <declare-styleable>
標簽的默認樣式同樣可以引用 MDC 主題樣式的屬性作為它們的值。
<!-- Copyright 2020 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!-- In res/values/attrs.xml -->
<declare-styleable name="AppCustomView">
<attr name="titleTextAppearance" />
<attr name="subtitleTextAppearance" />
...
</declare-styleable>
<!-- In res/values/styles.xml -->
<style name="Widget.App.CustomView" parent="android:Widget">
<item name="titleTextAppearance">?attr/textAppearanceHeadline6</item>
<item name="subtitleTextAppearance">?attr/textAppearanceBody2</item>
...
</style>
下一步
我們已經(jīng)在 Android 應用中實現(xiàn)了 MDC 字體樣式主題。有關 Material 主題的其他課題,請閱讀該系列其他文章。
- 打造 Material 顏色主題 | 實現(xiàn)篇
- 打造 Material 形狀主題 | 實現(xiàn)篇
- 使用 Material Design 組件實現(xiàn)深色主題
- 使用 Material Design 組件實現(xiàn) Material 動效
- 推薦開發(fā)者使用 Material Design 組件