EmojiCompat
支持库旨在让 Android 设备及时兼容最新的表情符号。它可防止您的应用以 ☐ 的形式显示缺少的表情符号字符,该符号表示您的设备没有用于显示文字的相应字体。通过使用 EmojiCompat
支持库,您的应用用户无需等到 Android OS 更新即可获取最新的表情符号。
![显示表情符号的设备](https://developer.android.google.cn/static/guide/topics/ui/images/look-and-feel/emoji-compat/emoji-comparison.png?authuser=0000&hl=bg)
请参阅以下相关资源:
EmojiCompat 的工作原理是怎样的?
EmojiCompat
支持库提供用于在搭载 Android 4.4(API 级别 19)及更高版本的设备上实现向后兼容表情符号支持的类。您可以为 EmojiCompat
配置捆绑式字体或可下载字体。如需详细了解配置,请参阅以下部分:
EmojiCompat
标识给定 CharSequence
的表情符号,根据需要将它们替换为 EmojiSpans
,最后呈现表情符号字形。图 2 演示了该流程。
![EmojiCompat 流程](https://developer.android.google.cn/static/guide/topics/ui/images/look-and-feel/emoji-compat/architecture.png?authuser=0000&hl=bg)
可下载字体配置
可下载字体配置使用可下载字体支持库功能来下载表情符号字体。它还会更新必要的 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。
库组件
![EmojiCompat 流程中的库组件](https://developer.android.google.cn/static/guide/topics/ui/images/look-and-feel/emoji-compat/basic-components.png?authuser=0000&hl=bg)
- 微件:
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
,则
可以使用 EmojiCompat
widget,从而扩展
AppCompat widgets
起。
- 将支持库添加到依赖项部分。
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
支持库,您必须在开发环境中修改应用项目的类路径依赖项。
如需将支持库添加到应用项目中,请执行以下操作:
- 打开应用的
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_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 支持库会使用多少内存?
- 我可以将 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。