EmojiCompat
支持库旨在让 Android 设备保持最新的表情符号。它能防止您的应用显示为 ☐ 形式的缺失表情符号,☐ 表示您的设备没有可显示该文本的字体。通过使用 EmojiCompat
支持库,您的应用用户无需等待 Android 操作系统更新即可获取最新的表情符号。

请参考以下相关资源
EmojiCompat 如何工作?
EmojiCompat
支持库提供了在运行 Android 4.4 (API level 19) 及更高版本的设备上实现向下兼容的表情符号支持的类。您可以使用打包字体或可下载字体来配置 EmojiCompat
。有关配置的更多信息,请参阅以下部分。
EmojiCompat
会识别给定 CharSequence
中的表情符号,并在需要时将其替换为 EmojiSpan
,最后渲染表情符号字形。图 2 演示了此过程。

可下载字体配置
可下载字体配置使用可下载字体支持库功能来下载表情符号字体。它还会更新 EmojiCompat
支持库所需的相关表情符号元数据,以便跟上最新的 Unicode 规范版本。
添加支持库依赖项
要使用 EmojiCompat
支持库,您必须修改开发环境中应用项目的 classpath 依赖项。
将支持库添加到您的应用项目
- 打开应用的
build.gradle
文件。 - 将支持库添加到
dependencies
部分。
Groovy
dependencies { ... implementation "androidx.emoji:emoji:28.0.0" }
Kotlin
dependencies { ... implementation("androidx.emoji:emoji:28.0.0") }
初始化可下载字体配置
您需要初始化 EmojiCompat
以加载元数据和字体。由于初始化可能需要一些时间,因此初始化过程在后台线程上运行。
要使用可下载字体配置初始化 EmojiCompat
,请执行以下步骤
- 创建
FontRequest
类的一个实例,并提供字体提供程序授权、字体提供程序软件包、字体查询以及证书哈希集列表。有关FontRequest
的更多信息,请参阅可下载字体文档的以编程方式使用可下载字体部分。 - 创建
FontRequestEmojiCompatConfig
的实例,并提供Context
和FontRequest
的实例。 - 通过调用
init()
方法并传递FontRequestEmojiCompatConfig
的实例来初始化EmojiCompat
。 - 在布局 XML 中使用
EmojiCompat
小部件。如果您使用的是AppCompat
,请参阅搭配使用 EmojiCompat 小部件与 AppCompat 部分。
Kotlin
class MyApplication : Application() { override fun onCreate() { super.onCreate() val fontRequest = FontRequest( "com.example.fontprovider", "com.example", "emoji compat Font Query", CERTIFICATES ) val config = FontRequestEmojiCompatConfig(this, fontRequest) EmojiCompat.init(config) } }
Java
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); FontRequest fontRequest = new FontRequest( "com.example.fontprovider", "com.example", "emoji compat Font Query", CERTIFICATES); EmojiCompat.Config config = new FontRequestEmojiCompatConfig(this, fontRequest); EmojiCompat.init(config); } }
<android.support.text.emoji.widget.EmojiTextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <android.support.text.emoji.widget.EmojiEditText android:layout_width="wrap_content" android:layout_height="wrap_content"/> <android.support.text.emoji.widget.EmojiButton android:layout_width="wrap_content" android:layout_height="wrap_content"/>
有关如何使用可下载字体配置配置 EmojiCompat
的更多信息,请访问 Emoji Compatibility 示例应用 Java | Kotlin。
库组件

- Widget:
EmojiEditText
、EmojiTextView
、EmojiButton
- 搭配
TextView
、EditText
和Button
使用EmojiCompat
的默认小部件实现。 EmojiCompat
- 支持库的主要公共接口。它负责所有外部调用并与系统的其他部分进行协调。
EmojiCompat.Config
- 配置要创建的单例实例。
EmojiSpan
- 一个
ReplacementSpan
子类,用于替换字符(序列)并渲染字形。 EmojiCompat
字体EmojiCompat
使用字体来显示表情符号。此字体是 Android 表情符号字体的修改版本。字体修改如下:- 为了提供渲染表情符号的向后兼容性,所有表情符号字符在 Unicode 的补充私用区 A (Supplemental Private Use Area-A) 中以单个 Unicode 码点表示,起始码点为 U+F0001。
- 额外的表情符号元数据以二进制格式插入到字体中,由
EmojiCompat
在运行时解析。数据嵌入在字体的meta
表中,带有私有标签 Emji。
配置选项
您可以使用 EmojiCompat
实例修改 EmojiCompat
的行为。您可以使用基类中的以下方法设置配置:
setReplaceAll()
:确定EmojiCompat
是否应将找到的所有表情符号替换为EmojiSpan
。默认情况下,EmojiCompat
会尽力判断系统是否可以渲染表情符号,并且不会替换这些表情符号。当设置为true
时,EmojiCompat
会将其找到的所有表情符号替换为EmojiSpan
。setEmojiSpanIndicatorEnabled()
:指示EmojiCompat
是否已将表情符号替换为EmojiSpan
。当设置为true
时,EmojiCompat
会为EmojiSpan
绘制背景。此方法主要用于调试。setEmojiSpanIndicatorColor()
:设置指示EmojiSpan
的颜色。默认值为GREEN
。registerInitCallback
:通知应用EmojiCompat
的初始化状态。
Kotlin
val config = FontRequestEmojiCompatConfig(...) .setReplaceAll(true) .setEmojiSpanIndicatorEnabled(true) .setEmojiSpanIndicatorColor(Color.GREEN) .registerInitCallback(object: EmojiCompat.InitCallback() { ... })
Java
EmojiCompat.Config config = new FontRequestEmojiCompatConfig(...) .setReplaceAll(true) .setEmojiSpanIndicatorEnabled(true) .setEmojiSpanIndicatorColor(Color.GREEN) .registerInitCallback(new InitCallback() {...})
添加初始化监听器
EmojiCompat
类提供了 registerInitCallback()
和 unregisterInitCallback()
方法来注册初始化回调。要使用这些方法,请创建 EmojiCompat.InitCallback
类的一个实例。调用这些方法并传递 EmojiCompat.InitCallback
类的实例。当 EmojiCompat
支持库初始化成功时,EmojiCompat
类会调用 onInitialized()
方法。如果库初始化失败,EmojiCompat
类会调用 onFailed()
方法。
要随时检查初始化状态,请调用 getLoadState()
方法。它返回以下值之一:LOAD_STATE_LOADING
、LOAD_STATE_SUCCEEDED
或 LOAD_STATE_FAILED
。
将 EmojiCompat 与 AppCompat widget 结合使用
如果您使用的是 AppCompat
小部件,则可以使用从 AppCompat
小部件扩展而来的 EmojiCompat
小部件。
- 将支持库添加到依赖项部分。
Groovy
dependencies { ... implementation "androidx.emoji:emoji-bundled:$version" }
Kotlin
dependencies { implementation("androidx.emoji:emoji-appcompat:$version") }
Groovy
dependencies { implementation "androidx.emoji:emoji-appcompat:$version" }
- 在布局 XML 中使用
EmojiCompat
AppCompat Widget
小部件。
<android.support.text.emoji.widget.EmojiAppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <android.support.text.emoji.widget.EmojiAppCompatEditText android:layout_width="wrap_content" android:layout_height="wrap_content"/> <android.support.text.emoji.widget.EmojiAppCompatButton android:layout_width="wrap_content" android:layout_height="wrap_content"/>
捆绑字体配置
EmojiCompat
支持库也提供打包字体版本。此软件包包含带有嵌入式元数据的字体。此软件包还包含一个使用 AssetManager
加载元数据和字体的 BundledEmojiCompatConfig
。
注意:字体的大小以兆字节计。
添加支持库依赖项
要使用带打包字体配置的 EmojiCompat
支持库,您必须修改开发环境中应用项目的 classpath 依赖项。
将支持库添加到您的应用项目
- 打开应用的
build.gradle
文件。 - 将支持库添加到
dependencies
部分。
Groovy
dependencies { ... implementation "androidx.emoji:emoji:28.0.0" }
Kotlin
dependencies { ... implementation("androidx.emoji:emoji:28.0.0") }
使用捆绑字体配置 EmojiCompat
要使用捆绑字体配置 EmojiCompat
,请执行以下步骤
- 使用
BundledEmojiCompatConfig
创建EmojiCompat
实例并提供Context
实例。 - 调用
init()
方法来初始化EmojiCompat
,并传递BundledEmojiCompatConfig
的实例。
Kotlin
class MyApplication : Application() { override fun onCreate() { super.onCreate() val config = BundledEmojiCompatConfig(this) EmojiCompat.init(config) } }
Java
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); EmojiCompat.Config config = new BundledEmojiCompatConfig(this); EmojiCompat.init(config); ... } }
不使用 widget 使用 EmojiCompat
EmojiCompat
使用 EmojiSpan
渲染正确的图像。因此,它必须将任何给定的 CharSequence
转换为带有 EmojiSpan
的 Spanned
实例。EmojiCompat
类提供了一种方法,可将 CharSequence
转换为带有 EmojiSpan
的 Spanned
实例。使用此方法,您可以处理并缓存已处理的实例而不是原始字符串,这可以提高应用的性能。
Kotlin
val processed = EmojiCompat.get().process("neutral face \uD83D\uDE10")
Java
CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");
为 IME 使用 EmojiCompat
通过使用 EmojiCompat
支持库,键盘可以渲染与其交互的应用支持的表情符号。IME 可以使用 hasEmojiGlyph()
方法检查 EmojiCompat
是否能够渲染表情符号。此方法接受一个表情符号的 CharSequence
,如果 EmojiCompat
可以检测和渲染该表情符号,则返回 true
。
键盘还可以检查应用支持的 EmojiCompat
支持库版本,以确定在调色板中渲染哪些表情符号。如需检查版本(如果可用),键盘需要检查 EditorInfo.extras
捆绑包中是否存在以下键:
EDITOR_INFO_METAVERSION_KEY
EDITOR_INFO_REPLACE_ALL_KEY
如果 bundle 中存在该键,则该值表示应用使用的表情符号元数据的版本。如果该键不存在,则应用未使用 EmojiCompat
。
如果此键存在并设置为 true
,则表示应用已调用 SetReplaceAll()
方法。有关 EmojiCompat
配置的更多信息,请参阅配置选项部分。
在 EditorInfo.extras
捆绑包中接收到键后,键盘可以使用 hasEmojiGlyph()
方法(其中 metadataVersion
是 EDITOR_INFO_METAVERSION_KEY
的值),以检查应用是否可以渲染特定的表情符号。
将 EmojiCompat 与自定义 widget 结合使用
您始终可以使用 process()
方法在应用中预处理 CharSequence
并将其添加到任何可以渲染 Spanned
实例的小部件中;例如,TextView
。此外,EmojiCompat
提供了以下小部件助手类,让您可以以最小的精力为自定义小部件添加表情符号支持。
- 示例 TextView
- 示例 EditText
Kotlin
class MyTextView(context: Context) : AppCompatTextView(context) { private val emojiTextViewHelper: EmojiTextViewHelper by lazy(LazyThreadSafetyMode.NONE) { EmojiTextViewHelper(this).apply { updateTransformationMethod() } } override fun setFilters(filters: Array<InputFilter>) { super.setFilters(emojiTextViewHelper.getFilters(filters)) } override fun setAllCaps(allCaps: Boolean) { super.setAllCaps(allCaps) emojiTextViewHelper.setAllCaps(allCaps) } }
Java
public class MyTextView extends AppCompatTextView { ... public MyTextView(Context context) { super(context); init(); } ... private void init() { getEmojiTextViewHelper().updateTransformationMethod(); } @Override public void setFilters(InputFilter[] filters) { super.setFilters(getEmojiTextViewHelper().getFilters(filters)); } @Override public void setAllCaps(boolean allCaps) { super.setAllCaps(allCaps); getEmojiTextViewHelper().setAllCaps(allCaps); } private EmojiTextViewHelper getEmojiTextViewHelper() { ... } }
Kotlin
class MyEditText(context: Context) : AppCompatEditText(context) { private val emojiEditTextHelper: EmojiEditTextHelper by lazy(LazyThreadSafetyMode.NONE) { EmojiEditTextHelper(this).also { super.setKeyListener(it.getKeyListener(keyListener)) } } override fun setKeyListener(input: KeyListener?) { input?.also { super.setKeyListener(emojiEditTextHelper.getKeyListener(it)) } } override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { val inputConnection: InputConnection = super.onCreateInputConnection(outAttrs) return emojiEditTextHelper.onCreateInputConnection( inputConnection, outAttrs ) as InputConnection } }
Java
public class MyEditText extends AppCompatEditText { ... public MyEditText(Context context) { super(context); init(); } ... private void init() { super.setKeyListener(getEmojiEditTextHelper().getKeyListener(getKeyListener())); } @Override public void setKeyListener(android.text.method.KeyListener keyListener) { super.setKeyListener(getEmojiEditTextHelper().getKeyListener(keyListener)); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { InputConnection inputConnection = super.onCreateInputConnection(outAttrs); return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs); } private EmojiEditTextHelper getEmojiEditTextHelper() { ... } }
常见问题解答
- 如何启动字体下载?
- 初始化需要多长时间?
- EmojiCompat 支持库使用多少内存?
- 我可以将 EmojiCompat 用于自定义 TextView 吗?
- 如果我在运行 Android 4.4(API 级别 19)或更低版本的设备上的布局 XML 中添加 widget,会发生什么?
表情符号字体会在首次请求时下载,如果设备上不存在。下载调度对应用是透明的。
字体下载后,初始化 EmojiCompat
大约需要 150 毫秒。
目前,用于查找表情符号的数据结构加载在应用的内存中,占用约 200KB。
可以。EmojiCompat 为自定义小部件提供了助手类。还可以预处理给定的字符串并将其转换为 Spanned
。有关小部件助手类的更多信息,请参阅搭配使用 EmojiCompat 与自定义小部件部分。
您可以在支持 Android 4.4 (API level 19) 或更低版本的设备的应用中包含 EmojiCompat
支持库或其小部件。但是,如果设备运行的 Android 版本低于 API level 19,EmojiCompat
及其小部件将处于“无操作”状态。这意味着 EmojiTextView
的行为与常规的 TextView
完全相同。EmojiCompat
实例;当您调用 init()
方法时,它会立即进入 LOAD_STATE_SUCCEEDED
状态。
更多资源
有关使用 EmojiCompat
库的更多信息,请观看 EmojiCompat。