该 EmojiCompat
支持库旨在使 Android 设备与最新的表情符号保持同步。它可以防止您的应用以 ☐ 的形式显示丢失的表情符号字符,这表示您的设备没有字体来显示文本。通过使用 EmojiCompat
支持库,您的应用用户无需等待 Android 操作系统更新即可获得最新的表情符号。
请参阅以下相关资源
EmojiCompat 如何工作?
该 EmojiCompat
支持库提供类来在运行 Android 4.4(API 级别 19)及更高版本的设备上实现向后兼容的表情符号支持。您可以使用捆绑字体或可下载字体配置 EmojiCompat
。有关配置的更多信息,请参阅以下部分
EmojiCompat
识别给定 CharSequence
的表情符号,如果需要,则将其替换为 EmojiSpans
,最后渲染表情符号字形。图 2 演示了该过程。
可下载字体配置
可下载字体配置使用可下载字体支持库功能下载表情符号字体。它还会更新 EmojiCompat
支持库需要跟上 Unicode 规范最新版本所必需的表情符号元数据。
添加支持库依赖项
要使用 EmojiCompat
支持库,您必须在开发环境中修改应用项目的类路径依赖项。
向您的应用程序项目添加支持库
- 打开应用程序的
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
的更多信息,请访问表情符号兼容性示例应用 Java | Kotlin。
库组件
- 小部件:
EmojiEditText
、EmojiTextView
、EmojiButton
- 默认小部件实现,用于将
EmojiCompat
与TextView
、EditText
和Button
一起使用。 EmojiCompat
- 支持库的主要公共表面。它执行所有外部调用并与系统的其他部分协调。
EmojiCompat.Config
- 配置要创建的单例实例。
EmojiSpan
- 一个
ReplacementSpan
子类,用于替换字符(序列)并渲染字形。 EmojiCompat
字体EmojiCompat
使用字体来显示表情符号。此字体是 Android 表情符号字体 的修改版本。字体修改如下- 为了提供向后兼容性以渲染表情符号,所有表情符号字符都以 Unicode 的补充专用区域 A 中的单个 Unicode 代码点表示,从 U+F0001 开始。
- 额外的表情符号元数据以二进制格式插入到字体中,并在运行时由
EmojiCompat
解析。数据嵌入到字体的meta
表中,使用私有标签 Emji。
配置选项
您可以使用 EmojiCompat
实例来修改 EmojiCompat
行为。您可以使用基类中的以下方法来设置配置
setReplaceAll()
:确定EmojiCompat
是否应将其找到的所有表情符号替换为EmojiSpans
。默认情况下,EmojiCompat
会尽力了解系统是否可以渲染表情符号,并且不会替换这些表情符号。当设置为true
时,EmojiCompat
会将其找到的所有表情符号替换为EmojiSpans
。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
和 EmojiCompat
类提供 registerInitCallback()
和 unregisterInitCallback()
方法来注册初始化回调。要使用这些方法,请创建 EmojiCompat.InitCallback
类的实例。调用这些方法并传递 EmojiCompat.InitCallback
类的实例。当 EmojiCompat
支持库的初始化成功时,EmojiCompat
类将调用 onInitialized()
方法。如果库初始化失败,EmojiCompat
类将调用 onFailed()
方法。
要随时检查初始化状态,请调用 getLoadState()
方法。它将返回以下值之一:LOAD_STATE_LOADING
、LOAD_STATE_SUCCEEDED
或 LOAD_STATE_FAILED
。
在 AppCompat 组件中使用 EmojiCompat
如果您使用的是 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 组件
组件。
<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
支持库也以捆绑字体版本提供。此软件包包含带有嵌入元数据的字体。该软件包还包括一个 BundledEmojiCompatConfig
,它使用 AssetManager
加载元数据和字体。
注意: 字体的尺寸为几兆字节。
添加支持库依赖项
要将 EmojiCompat
支持库与捆绑字体配置一起使用,您**必须**在开发环境中修改应用项目的类路径依赖项。
向您的应用程序项目添加支持库
- 打开应用程序的
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); ... } }
在没有组件的情况下使用 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");
将 EmojiCompat 用于 IME
使用 EmojiCompat
支持库,键盘可以渲染其交互的应用程序支持的表情符号。IME 可以使用 hasEmojiGlyph()
方法检查 EmojiCompat
是否能够渲染表情符号。此方法采用表情符号的 CharSequence
并返回 true
(如果 EmojiCompat
可以检测和渲染表情符号)。
键盘还可以检查应用程序支持的 EmojiCompat
支持库的版本,以确定在调色板中渲染哪些表情符号。要检查版本(如果可用),键盘需要检查 EditorInfo.extras
捆绑包中是否存在以下键
EDITOR_INFO_METAVERSION_KEY
EDITOR_INFO_REPLACE_ALL_KEY
如果该键存在于捆绑包中,则该值表示应用程序使用的表情符号元数据版本。如果此键不存在,则表示应用程序未使用 EmojiCompat
。
如果该键存在且设置为 true
,则表示应用程序已调用 SetReplaceAll()
方法。有关 EmojiCompat
配置的更多信息,请参阅配置选项部分。
在收到 EditorInfo.extras
捆绑包中的键后,键盘可以使用 hasEmojiGlyph()
方法(其中 metadataVersion
是 EDITOR_INFO_METAVERSION_KEY
的值)来检查应用程序是否可以渲染特定表情符号。
将 EmojiCompat 与自定义组件一起使用
您始终可以使用 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 支持库使用多少内存?
- 我可以在自定义 TextView 中使用 EmojiCompat 吗?
- 如果在运行 Android 4.4(API 级别 19)或更低版本的设备上在布局 XML 中添加组件会发生什么情况?
如果设备上不存在表情符号字体,则在第一次请求时下载。下载计划对应用程序是透明的。
下载字体后,初始化 EmojiCompat
大约需要 150 毫秒。
目前,查找表情符号的数据结构加载到应用程序的内存中,大约使用 200KB。
可以。EmojiCompat 为自定义组件提供帮助程序类。也可以预处理给定的字符串并将其转换为 Spanned
。有关组件帮助程序类的更多信息,请参阅将 EmojiCompat 与自定义组件一起使用部分。
您可以在支持运行 Android 4.4(API 级别 19)或更低版本的设备的应用程序中包含 EmojiCompat
支持库或其组件。但是,如果设备运行的是 Android 4.4 之前的版本,则 EmojiCompat
及其组件将处于“无操作”状态。这意味着 EmojiTextView
的行为与普通的 TextView
完全相同。EmojiCompat
实例;当您调用 init()
方法时,它将立即进入 LOAD_STATE_SUCCEEDED
状态。
其他资源
有关使用 EmojiCompat
库的更多信息,请观看EmojiCompat。