EmojiCompat
支持库旨在使Android设备与最新的Emoji保持同步。它可以防止您的应用以☐的形式显示缺失的Emoji字符,这表示您的设备没有显示文本的字体。通过使用EmojiCompat
支持库,您的应用用户无需等待Android操作系统更新即可获得最新的Emoji。
请参考以下相关资源
EmojiCompat如何工作?
EmojiCompat
支持库提供类来在运行Android 4.4(API级别19)及更高版本的设备上实现向后兼容的Emoji支持。您可以使用捆绑的字体或可下载的字体来配置EmojiCompat
。有关配置的更多信息,请参考以下部分
EmojiCompat
识别给定CharSequence
的Emoji,根据需要将其替换为EmojiSpans
,最后呈现Emoji字形。图2演示了此过程。
可下载字体配置
可下载字体配置使用可下载字体支持库功能下载Emoji字体。它还会更新EmojiCompat
支持库需要跟上Unicode规范最新版本所必需的Emoji元数据。
添加支持库依赖项
要使用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
的更多信息,请访问Emoji Compatibility示例应用 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
类提供 registerInitCallback()
和 unregisterInitCallback()
方法来注册初始化回调。要使用这些方法,请创建 EmojiCompat.InitCallback
类的实例。调用这些方法并传递 EmojiCompat.InitCallback
类的实例。当 EmojiCompat
支持库的初始化成功时,EmojiCompat
类会调用 onInitialized()
方法。如果库初始化失败,EmojiCompat
类会调用 onFailed()
方法。
要随时检查初始化状态,请调用 getLoadState()
方法。它返回以下值之一:LOAD_STATE_LOADING
、LOAD_STATE_SUCCEEDED
或 LOAD_STATE_FAILED
。
将 EmojiCompat 与 AppCompat 小部件一起使用
如果您正在使用 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
转换为带有 EmojiSpans
的 Spanned
实例。EmojiCompat
类提供了一种方法,可以将 CharSequences
转换为带有 EmojiSpans
的 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 支持库使用多少内存?
- 我可以将 EmojiCompat 用于自定义 TextView 吗?
- 如果我在运行 Android 4.4(API 级别 19)或更低版本的设备上在布局 XML 中添加小部件会发生什么情况?
如果设备上不存在表情符号字体,则会在第一次请求时下载。下载调度对应用程序是透明的。
下载字体后,初始化 EmojiCompat
大约需要 150 毫秒。
目前,查找表情符号的数据结构加载到应用程序的内存中,大约使用 200KB。
可以。EmojiCompat 为自定义小部件提供帮助程序类。也可以预处理给定的字符串并将其转换为 Spanned
。有关小部件帮助程序类的更多信息,请参阅 将 EmojiCompat 与自定义小部件一起使用 部分。
您可以在支持运行 Android 4.4(API 级别 19)或更低版本的设备的应用程序中包含 EmojiCompat
支持库或其小部件。但是,如果设备运行的是低于 API 级别 19 的 Android 版本,则 EmojiCompat
及其小部件处于“无操作”状态。这意味着 EmojiTextView
的行为与普通的 TextView
完全相同。EmojiCompat
实例;当您调用 init()
方法时,它会立即进入 LOAD_STATE_SUCCEEDED
状态。
其他资源
有关使用 EmojiCompat
库的更多信息,请观看 EmojiCompat 视频。