打造 Material 字體樣式主題 | 實現篇

使用 Material 主題 (Theming) 自定義 Material 組件,目的是讓組件觀感與品牌保持一致。Material 主題包括 顏色字體形狀 參數,您能夠對這些參數進行調整來得到近乎無限的組件變體,同時保持其核心結構和易用性。html

自版本 1.1.0 開始,您能夠在 Android 中使用 Material 組件 (Material Design Components, MDC) 庫 來實現 Material 主題。若是您要從設計支持庫 (Design Support Library) 或 MDC 1.0.0 遷移至新版 MDC,請參閱咱們提供的遷移指南—— 遷移至 Android Material 組件java

本文將重點討論如何實現字體樣式主題。android

字體樣式屬性

Material Design 提供 13 種適用於應用中全部文字的 "樣式 (styles)",每一種樣式都有一個設計術語 (例如 "Body 1") 以及對應的字體樣式屬性,您能夠在應用主題中覆寫這些屬性 (例如 textAppearanceBody1)。每一種樣式的屬性都有默認的 "基準" 值 (文字尺寸、字符間距、大小寫等)。git

△ 具備基準值的 MDC 字體樣式屬性

△ 具備基準值的 MDC 字體樣式屬性github

Material 組件使用這些字體樣式屬性來爲組件的文本元素設置樣式,這些組件一般繼承自 TextView 或組合了一個或多個 TextView。segmentfault

△ 一個按鈕中使用的字體樣式屬性 (紅色)

△ 一個按鈕中使用的字體樣式屬性 (紅色)緩存

字體樣式屬性在佈局和組件樣式中的應用以下:app

android:textAppearance=」?attr/textAppearanceBody1」

關於字體樣式屬性的使用,以及多種樣式化方案同時使用時被應用的優先級順序,如需瞭解更多,請查閱 Nick Butcher 的文章 —— "如何實現文字外觀"。ide

在 MDC 主題中,這些屬性會映射到樣式上,例如:工具

<style name=」Theme.MaterialComponents.*」 parent="...">
   ...
   <item name=」textAppearanceBody1」>
       @style/TextAppearance.MaterialComponents.Body1
   </item>
<style />

您也許在 AppCompat 或平臺中已經接觸過 TextAppearance 樣式,咱們將在本文的 字體樣式資源 部分進行詳細介紹。其對應的屬性是 MDC 的新增內容,使您可以根據不一樣主題變換不一樣文字樣式。

選擇字體樣式

釐清應該選擇使用何種字體樣式以及其中的屬性值也許是設計師的責任,也許它們源自您的品牌。然而,瞭解每一種樣式的做用及其使用場景是很是有用的:

  • textAppearanceHeadline* 樣式應用於標題
  • textAppearanceSubtitle* 樣式應用於副標題
  • textAppearanceBody* 樣式應用於多行文本正文
  • textAppearanceButton 樣式應用於按鈕,可是一樣也適用於其餘組件的部份內容,例如 Tab 和彈窗中的操做
  • textAppearanceCaption 樣式應用於小號文本,例如輸入框的提示和錯誤信息
  • textAppearanceOverline 樣式也應用於小號文本,可是它具備大寫英文字母和更大的字符間距,所以更適合於小標題和 Label,例如日期選擇器的標題

字體樣式工具

Material Design 提供了一個實用工具,它能夠預覽字型縮放,集成了 Google Font,而且能夠導出代碼。請查閱 Material Design 字體樣式指南 中的 "字型縮放生成器"。

△ Google Font (左) 和字型縮放生成器 (右)

△ Google Font (左) 和字型縮放生成器 (右)

字體樣式資源

字體樣式資源由字體和 TextAppearance 樣式組成。讓咱們來看看 Android 中可用的資源以及聲明樣式時的注意事項。

XML 和可下載字體

字體存放於 res/font 目錄下,經過 @font/ 符號引用。您可使用本地的 XML 字體 或者 可下載字體。Android Studio 內置了嚮導以幫助您開始使用可下載字體,包括配置必要的證書和清單元數據。請查閱由 Rod Sheeter 撰寫的 "助力 Android 開發者實現更好的排版指南" 來了解關於字體預加載更詳細的指南和進一步的優化。

咱們一般推薦使用可下載字體,由於它們會藉助共享字體提供程序的緩存來減少應用包體積。可是,可下載字體目前僅可以使用 Google Font 上的字體。若是您的應用須要使用已購買的字體或專用字體,請使用 XML 字體。

一樣值得注意的是,從 API 26 開始,Android 支持使用可變字體。請查閱 Rebecca Franks 的文章 —— "Android O 上的可變字體🖍" 以瞭解更多信息。

TextAppearance 樣式

TextAppearance 樣式能夠被當成是 Android 上的 Material Design 字體樣式。對於自定義的樣式,咱們推薦兩種方法來幫您實現關注點分離,併爲應用中的字體樣式主題值建立單一的數據來源:

  • 將全部 TextAppearance 樣式存放在同一個 res/values/type.xml 文件中
  • 使用 MDC TextAppearance 做爲父樣式,並遵照相同的命名規則

這些樣式中可以使用的屬性和值與 TextView 支持的屬性和值一致:

  • fontFamily 定義字族,一般使用 @font/ 資源引用 XML 或可下載字體
  • android:textSize 定義文本的大小,一般是一個 sp 尺寸
  • android:textColor 定義文本的顏色
  • android:letterSpacing 定義字符的間距
  • android: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 和行高

系統版本的 TextView 在 API 28 中添加了 android:lineHeight 屬性。MDC 經過 MaterialTextView 類爲該屬性提供了向下兼容能力。您不須要直接在佈局中使用該類,由於 MaterialComponentsViewInflater 會自動將 <TextView> 替換爲 MaterialTextView

您能夠在多種場景中使用 lineHeight:

  • 做爲一個 item 被包含於 TextAppearance 樣式中 (使用 android:textAppearance="..." 應用該樣式)
  • 做爲一個 item 被包含於父樣式爲 Widget.MaterialComponents.TextView 的組件樣式中 (使用 style="..." 應用該樣式)
  • 直接應用於佈局中的 <TextView>

△ 不一樣的行高值

△ 不一樣的行高值

注意事項

  • 您沒必要覆寫所有字體樣式。可是請注意,默認的 MDC 樣式使用系統字體 (一般是 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>

額外的字體樣式

若是您的設計系統須要的字體樣式在 Material 主題提供的 13 種樣式外,慶幸的是在 Android 中實現起來相對簡單,您能夠經過以下方式聲明樣式屬性:

<!-- 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>

覆寫應用主題中的字體樣式

接下來,咱們來討論如何經過覆寫相應屬性,將您選擇的字體樣式添加到應用主題中。

首先,咱們建議您設置主題以便優雅地處理淺色和深色調色板,同時也能夠減小與基本主題的重複。如需瞭解更多此話題相關信息,請參閱 Chris Banes 撰寫的 深色主題文章,以及他和 Nick Butcher 的演講 —— "使用樣式開發主題"。

設置完成後,在您應用的基本主題中覆寫您想要改變的字體樣式屬性:

<!-- 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 組件會響應主題級的字體樣式覆寫:

△ Material 組件響應主題級的字體樣式覆寫

△ Material 組件響應主題級的字體樣式覆寫

MDC 組件中的字體樣式

您已經知道 MDC 組件會響應主題級的樣式覆寫。可是您如何知道諸如某個按鈕使用 textAppearanceButton 做爲它文本標籤的樣式呢?讓咱們來看看如下幾種方式。

構建 Material 主題

構建 Material 主題 是一個可交互的 Android 項目,您能夠經過它修改顏色、字體樣式、形狀的值來建立您本身的 Material 主題。它還包含了全部主題參數和組件的目錄。您能夠按以下步驟來肯定哪些組件會響應主題字體樣式屬性的改變:

△ 構建 Material 主題中的字體樣式變化

△ 構建 Material 主題中的字體樣式變化

MDC 開發者文檔

MDC 開發者文檔已於最近更新。在本次更新中,咱們加入了屬性表,涵蓋了開發庫中所使用的設計術語和屬性默認值。例以下面是更新的 按鈕文檔 的 "Anatomy and key properties" (詳解和關鍵屬性) 部分。

△ MDC 按鈕開發者文檔中屬性表包含了字體樣式的默認值

源碼

檢索 MDC 源碼能夠說是最可靠的方式。MDC 使用默認樣式來實現 Material 主題,所以能夠查看這些樣式以及任何可樣式化屬性和 Java 文件。例如,查閱 MaterialButton 的 樣式屬性Java 文件

△ MDC 按鈕默認樣式中使用的字體樣式

△ MDC 按鈕默認樣式中使用的字體樣式

自定義 View 中的字體樣式

您的應用中也許會引入您本身開發或現有庫中的自定義組件。當它們與標準 MDC 組件共同使用時,有必要保證它們能響應 Material 主題變化。如下是爲自定義組件支持樣式主題化的注意事項。

在 <declare-styleable> 和默認樣式中使用 MDC 屬性

當自定義 View 使用了 <declare-styleable> 標籤時將可被樣式化。複用 MDC 中的 attr name 有利於保持統一。使用 <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>

下一步

咱們已經在 Android 應用中實現了 MDC 字體樣式主題。有關 Material 主題的其餘課題,請閱讀該系列其餘文章。

咱們一如既往地期待您在 GitHub 上提交 錯誤報告功能需求。另外請務必查看 Android 示例應用

歡迎您與咱們 分享 您實現的字體樣式主題。若是您遇到任何問題,請經過下方二維碼向咱們提交反饋:

相關文章
相關標籤/搜索