使用可下载字体

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

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

可下载字体提供以下优势

  • 减小应用程序大小,从而提高应用程序安装成功率。
  • 改善整体系统健康状况,因为多个应用程序可以通过提供程序共享相同的字体。这为用户节省了蜂窝数据、手机内存和磁盘空间。在此模型中,字体在需要时通过网络获取。
要体验可下载字体的实际操作,请参阅 DownloadableFonts 示例应用。

可下载字体是如何工作的?

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

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

基础知识

您可以通过以下方式使用可下载字体功能,这些方式将在后面的部分中详细介绍

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

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

  1. 布局编辑器中,选择一个TextView。然后,在属性下,选择fontFamily > 更多字体
    An image showing Android Studio Layout Editor
    图 2. 使用布局编辑器
    资源窗口将出现。
  2. 菜单中,选择Google 字体
  3. 字体框中,在“可下载”区域下选择字体。
  4. 选择创建可下载字体,然后单击确定
    An image showing how to select fonts from the Resources window
    图 3.资源窗口中选择字体。
  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 字体
    • 用于验证提供程序身份的证书的散列集列表。

    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类的实例
    • 接收字体请求结果的回调
    • 在线程上获取字体的处理程序

以下示例代码说明了可下载字体的整体过程

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:2.2.0"
}

Kotlin

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

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

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

  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)

在清单中预声明字体

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

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

  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. 使用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中的可下载字体