支持现代表情符号

标准的表情符号集 每年由 Unicode 刷新,因为表情符号的使用量在所有类型的应用程序中都在快速增长。

如果您的应用程序显示互联网内容或提供文本输入,我们强烈建议支持最新的表情符号字体。否则,以后的表情符号可能会显示为一个小方框,称为豆腐(☐)或其他渲染错误的表情符号序列。

Android 版本 11(API 级别 30)及更低版本无法更新表情符号字体,因此在这些版本上显示表情符号的应用程序必须手动更新。

以下是现代表情符号的示例。

示例 版本
🫠 🫱🏼‍🫲🏿 🫰🏽 14.0(2021 年 9 月)
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1(2020 年 9 月)
🥲 🥷🏿 🐻‍❄️ 13.0(2020 年 3 月)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1(2019 年 10 月)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0(2019 年 2 月)

androidx.emoji2:emoji2 库为较低版本的 Android 提供了更简单的向后兼容性。 emoji2 库是 AppCompat 库的依赖项,不需要进一步配置即可使用。

Compose 中的表情符号支持

2023 年 3 月 BOMCompose UI 1.4)支持最新版本的表情符号,包括向后兼容旧版 Android 版本,最低至 API 21。本页介绍如何在 View 系统中配置现代表情符号。有关更多信息,请参阅 Compose 中的表情符号 页面。

先决条件

要确认您的应用程序是否正确显示了更新的表情符号,请在运行 Android 10(API 级别 29)或更低版本的设备上启动它。本页包含可用于测试的现代表情符号。

使用 AppCompat 支持最新的表情符号

AppCompat 1.4 包含对表情符号的支持。

要使用 AppCompat 支持表情符号,请执行以下操作

  1. 检查您的模块是否依赖于 AppCompat 库版本 1.4.0-alpha01 或更高版本。

    build.gradle
    
    // Ensure version is 1.4.0-alpha01 or higher.
    implementation "androidx.appcompat:appcompat.$appcompatVersion"
    
  2. 确保所有显示文本的活动都扩展了 AppCompatActivity 类。

    Kotlin

    MyActivity.kt
    
    class MyActivity: AppCompatActivity {
    ...
    }
    

    Java

    MyActivity.java
    
    class MyActivity extends AppCompatActivity {
    ...
    }
    
  3. 通过在运行 Android 10 或更低版本的设备上启动您的应用程序并显示以下测试字符串来测试您的集成。确保所有字符都正确渲染。

    • 14.0:🫠,🫱🏼‍🫲🏿,🫰🏽
    • 13.1:😶‍🌫️,🧔🏻‍♀️,🧑🏿‍❤️‍🧑🏾
    • 13.0:🥲,🥷🏿,🐻‍❄️
    • 12.1:🧑🏻‍🦰,🧑🏿‍🦯,👩🏻‍🤝‍👩🏼
    • 12.0:🦩,🦻🏿,👩🏼‍🤝‍👩🏻

您的应用程序会自动在所有提供 emoji2 兼容可下载字体提供程序的设备(例如,由 Google Play 服务 提供支持的设备)上显示向后兼容的表情符号。

如果您的应用程序正在使用 AppCompat,但显示的是豆腐(☐)

在某些情况下,您的应用程序可能会显示豆腐而不是正确的表情符号,即使您添加了 AppCompat 库。以下是可能的解释和解决方案。

您正在最近刷新的设备或新模拟器上运行应用程序

清除应用程序的 Google Play 服务数据,以清除启动过程中可能发生的任何字体缓存。这通常会在几个小时后解决问题。

要清除应用程序数据,请执行以下操作

  1. 在您的 Android 设备上打开设置

  2. 点击应用程序和通知

  3. 点击查看所有应用程序应用程序信息

  4. 滚动浏览应用程序,然后点击Google Play 服务

  5. 点击存储和缓存

  6. 点击清除缓存

您的应用程序未使用 AppCompat 文本相关类

如果未扩展 AppCompatActivity,或者您在代码中实例化了视图(例如 TextView),则可能会发生这种情况。检查以下内容

  • 该活动扩展了 AppCompatActivity
  • 如果在代码中创建视图,请使用正确的 AppCompat 子类

AppCompatActivity 在膨胀 XML 时会自动膨胀 AppCompatTextView 以代替 TextView,因此您无需更新 XML。

测试手机不支持可下载字体

验证 DefaultEmojiCompatConfig.create 是否返回了非空配置。

较早 API 级别上的模拟器未升级 Google Play 服务

在较早 API 级别上使用模拟器时,您可能需要更新捆绑的 Google Play 服务,以使 emoji2 找到字体提供程序。为此,请在模拟器上登录 Google Play 商店。

要验证是否安装了兼容版本,请执行以下操作

  1. 运行以下命令

    adb shell dumpsys package com.google.android.gms | grep version
    
  2. 检查 versionCode 是否高于 211200000

在没有 AppCompat 的情况下支持表情符号

如果您的应用程序无法包含 AppCompat,它可以直接使用 emoji2。这需要更多工作,因此只有在您的应用程序无法使用 AppCompat 时才使用此方法。

要支持没有 AppCompat 库的表情符号,请执行以下操作

  1. 在您的应用程序的 build.gradle 文件中,包含 emoji2emoji2-views

    build.gradle
    
    def emojiVersion = "1.0.0-alpha03"
    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-views:$emojiVersion"
    

    emoji2-views 模块提供了 子类,例如 TextViewButtonEditText,它们实现了 EmojiCompat。不要在包含 AppCompat 的应用程序中使用它,因为它已经实现了 EmojiCompat

  2. 在 XML 和代码中(无论您在何处使用 TextViewEditTextButton),请改用 EmojiTextViewEmojiEditTextEmojiButton

    activity_main.xml
    
    <androidx.emoji2.widget.EmojiTextView ... />
    <androidx.emoji2.widget.EmojiEditText ... />
    <androidx.emoji2.widget.EmojiButton ... />
    

    通过包含 emoji2 模块,系统会使用默认的可下载字体提供程序在应用程序启动后不久 自动加载表情符号字体。不需要进一步配置。

  3. 要测试您的集成,请在运行 Android 11 或更低版本的设备上启动您的应用程序,并显示以下测试字符串。确保所有字符都正确渲染。

    • 14.0:🫠,🫱🏼‍🫲🏿,🫰🏽
    • 13.1:😶‍🌫️,🧔🏻‍♀️,🧑🏿‍❤️‍🧑🏾
    • 13.0:🥲,🥷🏿,🐻‍❄️
    • 12.1:🧑🏻‍🦰,🧑🏿‍🦯,👩🏻‍🤝‍👩🏼
    • 12.0:🦩,🦻🏿,👩🏼‍🤝‍👩🏻

在没有小部件的情况下使用 EmojiCompat

EmojiCompat 使用 EmojiSpan 来渲染正确的图像。因此,它必须将任何给定的 CharSequence 对象转换为具有 EmojiSpan 对象的 Spanned 对象。EmojiCompat 类提供了 process() 方法来将 CharSequences 转换为 Spanned 实例。使用此方法,您可以在后台调用 process() 并缓存结果,这会提高应用程序的性能。

Kotlin

val processed = EmojiCompat.get().process("neutral face \uD83D\uDE10")

Java

CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");

将 EmojiCompat 用于输入法编辑器

EmojiCompat 类允许键盘渲染它们与之交互的应用程序支持的表情符号。 输入法编辑器 (IME) 可以使用 getEmojiMatch() 方法来检查 EmojiCompat 实例是否能够渲染表情符号。此方法接收表情符号的 CharSequence,如果 EmojiCompat 可以检测和渲染表情符号,则返回 true

键盘还可以检查应用程序支持的 EmojiCompat 版本,以确定在调色板中渲染哪些表情符号。要检查版本(如果可用),键盘可以在 EditorInfo.extras 捆绑包中查找以下键

  • EDITOR_INFO_METAVERSION_KEY:表示应用程序使用的表情符号元数据的版本。如果此键不存在,则应用程序未使用 EmojiCompat
  • EDITOR_INFO_REPLACE_ALL_KEY:如果此键存在且设置为 true,则应用程序将配置 EmojiCompat 以替换所有表情符号,即使它们存在于系统中也是如此。

详细了解如何 配置 EmojiCompat 实例

在自定义视图中使用表情符号

如果您的应用包含 自定义视图,这些视图是 TextView 的直接或间接子类——例如,ButtonSwitchEditText——并且这些视图可以显示用户生成的内容,则它们必须分别实现 EmojiCompat

具体过程取决于您的应用是否使用 AppCompat 库。

为使用 AppCompat 的应用添加自定义视图

如果您的应用使用 AppCompat,请扩展 AppCompat 实现而不是平台实现。使用下表作为在 AppCompat 中扩展视图的指南。

不要扩展... 扩展
TextView AppCompatTextView
EditText AppCompatEditText
ToggleButton AppCompatToggleButton
Switch SwitchCompat
Button AppCompatButton
CheckedTextView AppCompatCheckedTextView
RadioButton AppCompatRadioButton
CheckBox AppCompatCheckBox
AutoCompleteTextView AppCompatAutoCompleteTextView
MultiAutoCompleteTextView AppCompatMultiAutoCompleteTextView

为不使用 AppCompat 的应用添加自定义视图

如果您的应用不使用 AppCompat,请使用 emoji2-views-helper 模块中的视图集成辅助程序,这些辅助程序专为在自定义视图中使用而设计。这些是 AppCompat 库用来实现表情符号支持的辅助程序。

完成以下步骤以支持不使用 AppCompat 的应用的自定义视图。

  1. 添加 emoji2-views-helper

    implementation "androidx.emoji2:emoji2-views-helper:$emojiVersion"
    
  2. 按照说明在您的应用的自定义视图中包含 EmojiTextViewHelperEmojiEditTextHelper

  3. 通过在运行 Android 10 或更低版本的设备上启动您的应用程序并显示以下测试字符串来测试您的集成。确保所有字符都正确渲染。

    • 14.0:🫠,🫱🏼‍🫲🏿,🫰🏽
    • 13.1:😶‍🌫️,🧔🏻‍♀️,🧑🏿‍❤️‍🧑🏾
    • 13.0:🥲,🥷🏿,🐻‍❄️
    • 12.1:🧑🏻‍🦰,🧑🏿‍🦯,👩🏻‍🤝‍👩🏼
    • 12.0:🦩,🦻🏿,👩🏼‍🤝‍👩🏻

处理 emoji2 的可选功能

在将 emoji2 库包含在您的应用中之后,您可以添加本节中介绍的可选功能。

配置 emoji2 以使用不同的字体或可下载字体提供程序

要配置 emoji2 以使用不同的字体或可下载字体提供程序,请执行以下操作

  1. 通过在清单中添加以下内容来禁用 EmojiCompatInitializer

    <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
               tools:node="remove" />
    </provider>
  2. 执行以下操作之一

修改您的 EmojiCompat 行为

您可以使用 EmojiCompat.Config 的实例来修改 EmojiCompat 行为。

最重要的配置选项是 setMetadataLoadStrategy(),它控制 EmojiCompat 何时加载字体。字体加载在调用 EmojiCompat.load() 时立即开始,这将触发任何必要的下载。系统将创建一个线程用于字体下载,除非您的应用提供一个线程。

LOAD_STRATEGY_MANUAL 使您可以控制何时调用 EmojiCompat.load(),而 LOAD_STRATEGY_DEFAULT 使加载在调用 EmojiCompat.init() 时同步开始。

大多数应用使用 LOAD_STRATEGY_MANUAL,以便他们可以控制字体加载的线程和时间。您的应用必须推迟到第一个屏幕显示之后,以避免引入启动延迟。 EmojiCompatInitializer 遵循此做法,并将加载表情符号字体推迟到第一个屏幕恢复之后。

使用基类的以下方法来设置配置的其他方面

  • setReplaceAll(): 确定 EmojiCompat 是否用 EmojiSpan 的实例替换它找到的所有表情符号。默认情况下,当 EmojiCompat 推断系统可以渲染表情符号时,它不会替换该表情符号。当设置为 true 时,EmojiCompat 将所有表情符号替换为 EmojiSpan 对象。
  • setEmojiSpanIndicatorEnabled(): 指示 EmojiCompat 是否用 EmojiSpan 对象替换表情符号。当设置为 true 时,EmojiCompat 会为 EmojiSpan 绘制背景。此方法主要用于调试目的。
  • setEmojiSpanIndicatorColor: 设置指示 EmojiSpan 的颜色。默认值为 GREEN
  • registerInitCallback(): 通知应用 EmojiCompat 初始化的状态。

添加初始化监听器

EmojiCompatEmojiCompat.Config 类提供 registerInitCallback()unregisterInitCallback() 方法来注册和取消注册初始化回调。您的应用使用这些回调来等待 EmojiCompat 初始化,然后您才能在后台线程或自定义视图中处理表情符号。

要使用这些方法,请创建 EmojiCompat.InitCallback 类的实例。调用这些方法并传入 EmojiCompat.InitCallback 类的实例。当初始化成功时,EmojiCompat 类将调用 onInitialized() 方法。如果库无法初始化,EmojiCompat 类将调用 onFailed() 方法。

要随时检查初始化状态,请调用 getLoadState() 方法。此方法将返回以下值之一:LOAD_STATE_LOADINGLOAD_STATE_SUCCEEDEDLOAD_STATE_FAILED

使用 emoji2 支持捆绑的字体

您可以使用 emoji2-bundled 工件将表情符号字体捆绑到您的应用中。但是,由于 NotoColorEmoji 字体的体积超过 10 MB,我们强烈建议您的应用尽可能使用可下载字体。 emoji2-bundled 工件专为不支持可下载字体的设备上的应用而设计。

要使用 emoji2-bundled 工件,请执行以下操作

  1. 包含 emoji2-bundledemoji2 工件

    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-bundled:$emojiVersion"
    
  2. 配置 emoji2 以使用捆绑的配置

    Kotlin

    EmojiCompat.init(BundledEmojiCompatConfig(context))
    

    Java

    EmojiCompat.init(new BundledEmojiCompatConfig(context));
    
  3. 按照前面关于包含 emojicompat(是否使用 AppCompat)的步骤测试集成。确保测试字符串正确显示。

    • 14.0:🫠,🫱🏼‍🫲🏿,🫰🏽
    • 13.1:😶‍🌫️,🧔🏻‍♀️,🧑🏿‍❤️‍🧑🏾
    • 13.0:🥲,🥷🏿,🐻‍❄️
    • 12.1:🧑🏻‍🦰,🧑🏿‍🦯,👩🏻‍🤝‍👩🏼
    • 12.0:🦩,🦻🏿,👩🏼‍🤝‍👩🏻

自动 EmojiCompat 配置的影响

系统使用启动库 EmojiCompatInitializerDefaultEmojiCompatConfig 应用默认配置。

在您的应用中第一个活动恢复后,初始化程序将安排表情符号字体加载。这种短暂的延迟使您的应用能够显示其初始内容,而不会出现由于后台线程中字体加载而导致的任何潜在延迟。

DefaultEmojiCompatConfig 会查找系统安装的可下载字体提供程序,该提供程序实现 EmojiCompat 接口(例如 Google Play 服务)。在由 Google Play 服务驱动的设备上,这将使用 Google Play 服务加载字体。

初始化程序创建一个后台线程来加载表情符号字体,字体下载可能需要长达 10 秒才能超时。字体下载完成后,在后台线程上初始化 EmojiCompat 大约需要 150 毫秒。

推迟 EmojiCompat 的初始化,即使您禁用了 EmojiCompatInitializer。如果您 手动配置 EmojiCompat,请在显示应用的第一个屏幕后调用 EmojiCompat.load(),以避免与第一个屏幕加载的后台争用。

加载后,EmojiCompat 将使用大约 300 KB 的 RAM 来保存表情符号元数据。