支持新式表情符号

随着用户越来越多地使用各种应用中的表情符号,Unicode 每年都会更新标准表情符号集。

如果您的应用显示互联网内容或提供文本输入,强烈建议您支持最新的表情符号字体。否则,较新的表情符号可能会显示为称为“豆腐块” (□) 的小方块或其他错误呈现的表情符号序列。

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

以下是一些新式表情符号的示例。

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

androidx.emoji2:emoji2 库可让您更轻松地向后兼容较低的 Android 版本。emoji2 库是 AppCompat 库的依赖项,不需要进一步的配置即可使用。

前提条件

如要确认您的应用会正确显示较新的表情符号,请在搭载以下某个版本的设备上启动应用:Android 4.4(API 级别 19)和 Android 10(API 级别 29)之间的版本(包含这两个版本)。本页面中提供了一些新式表情符号,您可以显示它们以进行测试。

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

AppCompat 1.4 支持在 Android 4.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. 确保显示文本的所有 activity 都扩展 AppCompatActivity 类。

    Kotlin

    MyActivity.kt
    
    class MyActivity: AppCompatActivity {
       …
    }
    

    Java

    MyActivity.java
    
    class MyActivity extends AppCompatActivity {
       …
    }
    
  3. 如需测试您的集成,请在搭载 Android 10 或更低版本的设备上启动应用,并显示以下测试字符串。确保所有字符都能正确呈现。

    • 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),就可能会发生这种情况。请确保以下几点:

  • activity 会扩展 AppCompatActivity
  • 如果在代码中创建视图,则使用正确的 appcompat subclass

在膨胀 XML 时,AppCompatActivity 会自动膨胀 AppCompatTextView 而不是 TextView,因此您无需更新自己的 XML。

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

请验证 DefaultEmojiCompatConfig.create 是否会返回非 null 配置。

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 10 或更低版本的设备上启动应用,并显示以下测试字符串。确保所有字符都能正确呈现。

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

不搭配微件使用 EmojiCompat

EmojiCompat 使用 EmojiSpan 呈现正确的图片。因此,它必须使用 EmojiSpan 对象将任何给定 [CharSequence] 对象转换为 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) 可以使用 hasEmojiGlyph() 方法检查 EmojiCompat 的实例是否能够呈现某个表情符号。此方法会接受表情符号的 CharSequence,如果 EmojiCompat 可以检测并呈现该表情符号,则返回 true

键盘还可以检查应用支持的 EmojiCompat 版本,以确定要在 palette 中呈现的表情符号。如需检查版本(如果可用),键盘可以在 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 或更低版本的设备上启动应用,并显示以下测试字符串。确保所有字符都能正确呈现。

    • 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. 如需测试集成,请按照上面有关在使用或不用 appcompat 的情况下添加 emojicompat 的步骤操作,并确保测试字符串可以正确显示。

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

自动化 EmojiCompat 配置的影响

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

在应用中第一个 activity 恢复后不久,初始化程序会安排加载表情符号字体。这种简短的延迟可让您的应用显示其初始内容,而不会因后台线程中在加载字体引入任何潜在的启动延迟时间。

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

初始化程序会创建一个后台线程以加载表情符号字体,字体可能需要最多 10 秒的时间下载完成,否则便为超时。下载字体后,在后台线程上初始化 EmojiCompat 大约需要 150 毫秒。

推迟 EmojiCompat 的初始化,即使您停用 EmojiCompatInitializer 也是如此。如果您手动配置 EmojiCompat,请在应用的第一个屏幕显示之后调用 EmojiCompat.load(),以免在首个屏幕加载时出现后台争用。

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