EmojiCompat 支持库旨在让 Android 设备及时兼容最新的表情符号。它可防止您的应用以 ☐ 的形式显示缺少的表情符号字符,该符号表示您的设备没有用于显示文字的相应字体。通过使用 EmojiCompat 支持库,您的应用用户无需等到 Android OS 更新即可获取最新的表情符号。
请参阅以下相关资源:
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()方法初始化EmojiCompat并传递FontRequestEmojiCompatConfig的实例。 - 在布局 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- 支持库的主要公开 Surface。它执行所有外部调用并与系统的其他部分协调。
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。
将 EmojiCompat 与 AppCompat 微件搭配使用
如果您使用的是 AppCompat widgets,则可以使用从 AppCompat widgets 扩展的 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 中使用
EmojiCompatAppCompat 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 支持库,您必须在开发环境中修改应用项目的类路径依赖项。
如需将支持库添加到应用项目中,请执行以下操作:
- 打开应用的
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 呈现正确的图片。因此,它必须使用 EmojiSpans 将任意给定 CharSequence 转换为 Spanned 实例。EmojiCompat 类提供了一种通过 EmojiSpans 将 CharSequences 转换为 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,如果 EmojiCompat 可检测并呈现表情符号,则返回 true。
键盘还可以检查应用支持的 EmojiCompat 支持库版本,以确定要在调色板中呈现的表情符号。如需检查版本(如果可用),键盘需要检查 EditorInfo.extras 软件包中是否存在以下键:
EDITOR_INFO_METAVERSION_KEYEDITOR_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 支持库会使用多少内存?
- 我可以将 EmojiCompat 用于自定义 TextView 吗?
- 如果我在搭载 Android 4.4(API 级别 19)或更低版本的设备上的布局 XML 中添加微件,会出现什么情况?
如果设备上不存在表情符号字体,会在首次请求时下载这些字体。下载调度对应用是透明的。
下载字体后,初始化 EmojiCompat 大约需要 150 毫秒。
目前,用于查找表情符号的数据结构加载到应用的内存中,约占 200KB。
可以。EmojiCompat 为自定义微件提供辅助程序类。也可以对给定字符串进行预处理并将其转换为 Spanned。如需详细了解微件辅助程序类,请参阅将 EmojiCompat 与自定义微件搭配使用部分。
如果您的应用支持搭载 Android 4.4(API 级别 19)或更低版本的设备,您可以在应用中添加 EmojiCompat 支持库或其微件。但是,如果设备搭载的 Android 版本低于 API 级别 19,EmojiCompat 及其微件将处于“无操作”状态。这意味着 EmojiTextView 的行为会与常规 TextView.EmojiCompat 实例完全相同;当您调用 init() 方法时,它会立即进入 LOAD_STATE_SUCCEEDED 状态。
其他资源
如需详细了解如何使用 EmojiCompat 库,请观看 EmojiCompat。