借助“可下载字体”功能,API 可从提供程序应用请求字体,而无需将文件打包到应用中或让应用下载字体。可下载字体可通过 AndroidX Core 库在搭载 Android API 版本 14 及更高版本的设备上使用。
可下载字体具有以下优势:
- 缩减应用大小,进而提高应用安装成功率。
- 提升系统的整体运行状况,因为多个应用可通过提供程序共用同一字体。这样可以帮用户节省移动数据网络流量、手机内存和磁盘空间。在此模型中,系统会在需要时通过网络提取字体。
可下载字体的工作方式是怎样的?
字体提供程序是一个应用,可检索字体并将其缓存在本地,以便其他应用可以请求获取和共用字体。下图演示了该流程。
基础知识
您可以通过以下方式使用可下载字体功能,下文将对此进行详细介绍:
将可下载字体与 Android Studio 和 Google Play 服务搭配使用
您可以将应用设置为使用 Android Studio 3.0 或更高版本来下载字体。为帮助您开始使用可下载字体功能,您可以使用 Google Play 服务提供的字体提供程序。
- 在 Layout Editor 中,选择一个
TextView
。然后,在 Attributes 下,依次选择 fontFamily > More Fonts。 此时,系统会显示 Resources 窗口。 - 在 Source 菜单中,选择 Google Fonts。
- 在 Fonts 框中,选择“Downloadable”(可下载)区域下的字体。
- 选择 Create downloadable font,然后点击 OK。
Android Studio 会自动生成在您的应用中正确呈现字体所需的相关 XML 文件。
以程序化方式使用可下载字体
从 Android 8.0(API 级别 26)开始,AndroidX Core 已全面支持可下载字体。如需详细了解如何使用 AndroidX Core 库,请参阅本页中的“可下载字体 AndroidX Core 库”部分。
如需以程序化方式使用可下载字体功能,请与以下两个关键类互动:
android.graphics.fonts.FontRequest
:此类让您可以创建字体请求。FontsContractCompat
:此类让您可以根据字体请求创建新的Typeface
对象。
您的应用会使用 FontsContract
API 从字体提供程序检索字体。每个提供程序对其支持的 Android 版本和查询语言都有自己的一组限制。如需详细了解 Android 版本和查询格式,请参阅提供程序的相关文档。
如需下载字体,请完成以下步骤:
- 创建
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);
- 创建
FontsContract.FontRequestCallback
类的实例。 - 替换
onTypefaceRetrieved()
方法,以指示字体请求已完成。将检索到的字体作为参数提供。您可以根据需要使用此方法来设置字体。例如,您可以对TextView
设置字体。 - 替换
onTypefaceRequestFailed()
方法,以接收有关字体请求过程中的错误的信息。如需详细了解错误代码,请参阅错误代码常量。 - 调用
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
软件包中包含 FontsContractCompat
和 FontRequest
类,可实现向后兼容的可下载字体功能支持。AndroidX 类包含与框架方法类似的方法,并且下载字体的过程与本页面中以程序化方式使用可下载字体部分中所述的过程类似。
如需使用 AndroidX 下载字体,请从 androidx.core.provider
软件包中导入 FontsContractCompat
和 FontRequest
类。创建这些类(而不是 FontsContract
和 android.graphics.fonts.FontRequest
框架类)的实例。
添加 AndroidX Core 依赖项
如需使用 FontsContractCompat
和 FontRequest
类,您必须在开发环境中修改应用项目的类路径依赖项。
如需将 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 布局中的资源。这意味着,不再需要将字体捆绑为资源。您可以为整个主题定义一个自定义字体,从而提升多个字重和样式(例如 bold、medium 或 light)的可用性。
- 在
res/font
文件夹中创建新的 XML 文件。 - 添加
<font-family>
根元素并设置与字体相关的属性,如以下示例 XML 文件所示: - 在布局 XML 文件中将文件作为
@font/font_file_name
引用。您还可以使用getFont()
方法以编程方式检索文件,例如getFont(R.font.font_file_name)
。
<?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>
在清单中预先声明字体
布局扩充和资源检索是同步任务。默认情况下,第一次尝试检索字体会触发字体提供程序请求,并因此增加第一次布局时间。为避免延迟,您可以预先声明需要在清单中检索的字体。在系统从提供程序检索字体后,该字体会立即变为可用状态。如果检索字体的时间长于预期,则系统会取消提取流程,并使用默认字体。
如需在清单中预先声明字体,请完成以下步骤:
- 在
res/values/arrays.xml
中创建一个资源数组,并声明要预提取的字体。 - 使用
meta-data
标签在清单中声明资源数组。
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>
<meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />
添加证书
如果未预安装字体提供程序或您要使用 AndroidX Core 库,请声明为字体提供程序签名所用的证书。系统会使用证书来验证字体提供程序的身份。
通过执行以下步骤来添加证书:
- 创建一个包含证书详情的字符串数组。如需详细了解证书详细信息,请参阅字体提供程序的相关文档。
- 将
fontProviderCerts
属性设置为数组。
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="certs"> <item>MIIEqDCCA5CgAwIBAgIJA071MA0GCSqGSIb3DQEBBAUAMIGUMQsww...</item> </string-array> </resources>
android:fontProviderCerts="@array/certs"