支持现代表情符号

尝试Compose方法
Jetpack Compose是推荐的Android UI工具包。了解如何在Compose中支持表情符号。

标准的表情符号集由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 并返回 true(如果 EmojiCompat 可以检测和渲染表情符号)。

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

  • 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秒钟才能超时。下载字体后,大约需要150毫秒才能在后台线程上初始化EmojiCompat

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

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