使用可下载字体

尝试 Compose 方式
Jetpack Compose 是 Android 推荐的 UI 工具包。了解如何在 Compose 中使用文本。

可下载字体功能允许 API 从提供程序应用请求字体,而不是将文件捆绑到应用中或让应用自行下载字体。可下载字体通过 AndroidX Core 库在运行 Android API 版本 14 及更高版本的设备上可用。

可下载字体具有以下优势

  • 减小应用大小,从而提高应用安装成功率。
  • 提高整体系统健康水平,因为多个应用可以通过提供程序共享同一字体。这为用户节省了蜂窝数据、手机内存和磁盘空间。在这种模式下,字体在需要时通过网络获取。
如需可下载字体的动手实践经验,请参阅 DownloadableFonts 示例应用。

可下载字体如何工作?

字体提供程序是一个应用,它检索字体并将其本地缓存,以便其他应用可以请求和共享字体。下图说明了该过程。

An images showing the main components in Emoji compat process
图 1. 可下载字体流程。

基础知识

您可以通过以下方式使用可下载字体功能,这些方式将在后面的章节中详细讨论

通过 Android Studio 和 Google Play 服务使用可下载字体

您可以使用 Android Studio 3.0 或更高版本设置应用以下载字体。为了帮助您开始使用可下载字体功能,您可以使用 Google Play 服务中的字体提供程序。

  1. Layout Editor 中,选择一个 TextView。然后,在 Attributes 下,选择 fontFamily > More Fonts
    An image showing Android Studio Layout Editor
    图 2. 使用 Layout Editor
    Resources 窗口将会出现。
  2. Source 菜单中,选择 Google Fonts
  3. Fonts 框中,在“Downloadable”区域下选择一个字体。
  4. 选择 Create downloadable font,然后点击 OK
    An image showing how to select fonts from the Resources window
    图 3.Resources 窗口中选择字体。
  5. Android Studio 会自动生成在应用中正确渲染字体所需的相应 XML 文件。

    An image showing how to preview fonts
    图 4. 预览字体文件。

以编程方式使用可下载字体

从 Android 8.0(API 级别 26)开始,AndroidX Core 完全支持可下载字体。有关使用 AndroidX Core 库的更多信息,请参阅本页面上的可下载字体 AndroidX Core 库部分

要以编程方式使用可下载字体功能,需要与两个关键类交互

您的应用使用 FontsContract API 从字体提供程序检索字体。每个提供程序对于支持的 Android 版本和查询语言都有自己的限制集。有关 Android 版本和查询格式的更多信息,请查阅您的提供程序文档。

要下载字体,请完成以下步骤

  1. 创建 android.graphics.fonts.FontRequest 类的实例,以从提供程序请求字体。要创建请求,请传递以下参数
    • 字体提供程序授权。
    • 字体提供程序软件包,用于验证提供程序身份。
    • 字体的字符串查询。有关查询格式的更多信息,请参阅您的字体提供程序文档,例如 Google Fonts
    • 用于验证提供程序身份的证书哈希集列表。

    Kotlin

    val request = FontRequest(
            "com.example.fontprovider.authority",
            "com.example.fontprovider",
            "my font",
            certs
    )

    Java

    FontRequest request = new FontRequest("com.example.fontprovider",
                       "com.example.fontprovider", "my font", certs);
  2. 创建 FontsContract.FontRequestCallback 类的实例。
  3. 覆盖 onTypefaceRetrieved() 方法以指示字体请求已完成。将检索到的字体作为参数提供。您可以使用此方法根据需要设置字体。例如,您可以设置 TextView 上的字体。
  4. 覆盖 onTypefaceRequestFailed() 方法以接收有关字体请求过程中错误的信息。有关错误代码的更多信息,请参阅错误代码常量
  5. 调用 FontsContract.requestFont() 方法从字体提供程序检索字体。此方法会启动检查以确定字体是否存在于缓存中。如果本地不可用,它会调用字体提供程序,异步检索字体,并将结果传递给回调。传递以下参数
    • Context 类的实例
    • android.graphics.fonts.FontRequest 类的实例
    • 用于接收字体请求结果的回调
    • 用于在线程上获取字体的 handler

以下示例代码演示了整个可下载字体流程

Kotlin

val request = FontRequest(
        "com.example.fontprovider.authority",
        "com.example.fontprovider",
        "my font",
        certs
)
val callback = object : FontsContract.FontRequestCallback() {

    override fun onTypefaceRetrieved(typeface: Typeface) {
        // Your code to use the font goes here.
        ...
    }

    override fun onTypefaceRequestFailed(reason: Int) {
        // Your code to deal with the failure goes here.
        ...
    }
}
FontsContract.requestFonts(context, request, handler, null, callback)

Java

FontRequest request = new FontRequest("com.example.fontprovider.authority",
        "com.example.fontprovider", "my font", certs);
FontsContract.FontRequestCallback callback =
    new FontsContract.FontRequestCallback() {
        @Override
        public void onTypefaceRetrieved(Typeface typeface) {
            // Your code to use the font goes here.
            ...
        }

        @Override
        public void onTypefaceRequestFailed(int reason) {
            // Your code to deal with the failure goes here.
            ...
        }
};
FontsContract.requestFonts(context, request, handler, null, callback);

有关如何从字体提供程序下载字体的更多信息,请参阅 DownloadableFonts 示例应用。

使用 AndroidX Core 可下载字体

AndroidX Core 在运行 Android API 版本 14 或更高版本的设备上提供对可下载字体功能的支持。androidx.core.provider 软件包包含 FontsContractCompatFontRequest 类,用于实现向后兼容的可下载字体功能支持。AndroidX 类包含与框架方法类似的方法,下载字体的过程与本页面上关于以编程方式使用可下载字体的部分描述的过程类似。

要使用 AndroidX 下载字体,请从 androidx.core.provider 软件包中导入 FontsContractCompatFontRequest 类。创建这些类的实例,而不是 FontsContractandroid.graphics.fonts.FontRequest 框架类。

添加 AndroidX Core 依赖项

要使用 FontsContractCompatFontRequest 类,您必须在开发环境中修改应用项目的类路径依赖项。

要将 AndroidX Core 添加到您的应用项目,请将以下依赖项添加到应用的 build.gradle 文件中

Groovy

dependencies {
    ...
    implementation "androidx.core:core-ktx:1.16.0"
}

Kotlin

dependencies {
    ...
    implementation("androidx.core:core-ktx:1.16.0")
}

在 XML 中将可下载字体用作资源

Android 8.0(API 级别 26)和 AndroidX Core 提供了一种更快、更方便的方式,可在 XML 布局中将自定义字体声明为资源。这意味着无需将字体捆绑为 asset。您可以为整个主题定义自定义字体,这可以提高在使用多种字重和样式(例如粗体、中等或细体)时的可用性。

  1. res/font 文件夹中创建一个新的 XML 文件。
  2. 添加一个 <font-family> 根元素并设置与字体相关的属性,如下面的示例 XML 文件所示
  3. <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:android="http://schemas.android.com/apk/res/android"
            android:fontProviderAuthority="com.example.fontprovider.authority"
            android:fontProviderPackage="com.example.fontprovider"
            android:fontProviderQuery="example font"
            android:fontProviderCerts="@array/certs">
    </font-family>
  4. 在布局 XML 文件中将该文件引用为 @font/font_file_name。您还可以使用 getFont() 方法以编程方式检索该文件,例如 getFont(R.font.font_file_name)

在 manifest 中预先声明字体

布局膨胀和资源检索是同步任务。默认情况下,首次尝试检索字体会触发对字体提供程序的请求,从而增加首次布局时间。为了避免延迟,您可以在 manifest 中预先声明需要检索的字体。系统从提供程序检索到字体后,即可立即使用。如果字体检索花费的时间超过预期,系统会中止获取过程并使用默认字体。

要在 manifest 中预先声明字体,请完成以下步骤

  1. res/values/arrays.xml 中创建一个资源数组,并声明要预取的字体。
  2. res/values/arrays.xml
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <array name="preloaded_fonts">
            <item>@font/font1</item>
            <item>@font/font2</item>
        </array>
    </resources>
  3. 在 manifest 中使用 meta-data 标签声明资源数组。
  4. <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />

添加证书

当字体提供程序未预安装,或者如果您使用的是 AndroidX Core 库时,需要声明字体提供程序使用的签名证书。系统使用这些证书来验证字体提供程序的身份。

执行以下步骤以添加证书

  1. 创建包含证书详细信息的字符串数组。有关证书详细信息的更多信息,请参阅您的字体提供程序文档。
  2. <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="certs">
           <item>MIIEqDCCA5CgAwIBAgIJA071MA0GCSqGSIb3DQEBBAUAMIGUMQsww...</item>
        </string-array>
    </resources>
  3. fontProviderCerts 属性设置为该数组。
  4. android:fontProviderCerts="@array/certs"

Compose 中的可下载字体