Most Popular Emojis
| 🎄 Christmas Tree | 🫶 Heart Hands | ❤️ Red Heart | 😊 Smiling Face with Smiling Eyes |
|---|---|---|---|
| ✨ Sparkles | 🎁 Wrapped Gift | 🎅 Santa Claus | 🥹 Face Holding Back Tears |
| 🔥 Fire | ❄️ Snowflake | 😂 Face with Tears of Joy | 🎉 Party Popper |
1. 简介
Emoji 表情符号是 Unicode 字符,Emoji 表情的国际标准在 2015 年出台,目前(2022年12月)已经是 **v15.0** 版本的标准了。Unicode 每年都会更新表情符号的标准集,用户对所有类型应用程序的表情符号使用量迅速增加。
如果我们的应用程序显示网络内容或提供文本输入,则我们需要支持最新的表情符号字体。否则,较新的表情符号可能会显示为 豆腐 (☐) 的小方框 或其他错误呈现的表情符号。
Android 11(API 级别 30)及更低版本不支持可下载的 Emoji 字体,无法更新表情符号字体,因此在这些较低版本的手机中不能正常显示最新的表情符,需要程序手动处理对 Emoji 的兼容,Android 官方提供了 androidx.emoji2:emoji2 兼容库。
但是 Jetpack Compose 默认的可组合函授 Text,只支持使用系统默认的字符集显示 emoji,根据 IssueTracker 中新功能的介绍,Compose 已经支持 EmojiCompat,但当我使用 Android 12 的设备按 官方建议方式检查对 emoji 的支持 时,v14.0 版本的 emoji 并不能正常显示。
本文主要介绍使用
appcompat, 和emoji2支持最新的表情符,这些是依赖与 GMS 提供的可下载字体的,关于没有 GMS 服务的手机怎样解决这个问题,将在接下来的文章介绍。
使用下面的表情符号示例来测试应用程序是否符合最新的 Unicode 版本:
| Examples | Unicode Version |
|---|---|
| 🫠 🫱🏼🫲🏿 🫰🏽 | https://emojipedia.org/emoji-14.0/ |
| 😶🌫️ 🧔🏻♀️ 🧑🏿❤️🧑🏾 | https://emojipedia.org/emoji-13.1/ |
| 🥲 🥷🏿 🐻❄️ | https://emojipedia.org/unicode-13.0/ |
| 🧑🏻🦰 🧑🏿🦯 👩🏻🤝👩🏼 | https://emojipedia.org/emoji-12.1/ |
| 🦩 🦻🏿 👩🏼🤝👩🏻 | https://emojipedia.org/emoji-12.0/ |

所以我在 Jetpack Compose 中继续通过 androidx.emoji2:emoji2 库来兼容最新的表情符号,这就需要用到 AndroidView 来渲染 Android 传统控件。其中也会遇到多个问题,下文会介绍
emoji2库提供了对 Android 4.4(API 级别 19)到 Android 10(API 级别 29)之间版本的最新表情符号的兼容。
调用 emoji2 的多种方式:
2. 使用 AppCompat 支持最新的 emoji
emoji2 库是 AppCompat 库的依赖项,使用 AppCompat 则无需其他配置即可工作。AppCompat 还提供了 AppCompatEditText AppCompatToggleButton AppCompatButton 等控件**。**
添加 appcompat 依赖(1.4.0-alpha01 或更高版本) :
// build.gradle
implementation 'androidx.appcompat:appcompat:1.4.1'
可组合函授:
@Composable
fun EmojiWithAppCompatTextView(textStr: String) {
AndroidView(
factory = { context ->
AppCompatTextView(context).apply {
setTextColor(Black.toArgb())
text = textStr
textSize = 24F
textAlignment = View.TEXT_ALIGNMENT_CENTER
}
},
update = {
it.apply {
text = textStr
}
}
)
}
效果:

如果应用使用的是传统的XML布局,使用 appcompat 时,也可用直接使用 AppCompatActivity 即可,它会自动使用 AppCompatTextView 代替 TextView,因此您无需更新 XML。
3. 使用 emoji2-views 支持最新的 emoji
// build.gradle
implementation "androidx.emoji2:emoji2:$emojiVersion"
implementation "androidx.emoji2:emoji2-views:$emojiVersion"
@Composable
fun EmojiWithEmojiTextView(textStr: String) {
AndroidView(
factory = { context ->
EmojiTextView(context).apply {
setTextColor(Black.toArgb())
text = processedText
textSize = 24F
textAlignment = View.TEXT_ALIGNMENT_CENTER
}
},
update = {
it.apply {
text = processedText
}
}
)
}
emoji2-views 提供了 EmojiTextView、EmojiEditText、EmojiButton、EmojiCompatProcess 、等,可用使用相似的方式调用。
4. 不使用 EmojiCompat 控件的情况下支持最新的 emoji
// build.gradle
implementation 'androidx.emoji2:emoji2:1.2.0'
// AndroidManifest.xml
<application
android:name=".MyApplication" >
...
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
tools:node="remove" />
</provider>
...
// application class
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
EmojiCompat.init(this)
}
}
@Composable
fun EmojiCompatProcess(
textString: String
) {
val processedText = EmojiCompat.get().process(textString)
AndroidView(
factory = { context ->
EmojiTextView(context).apply {
setTextColor(Black.toArgb())
text = processedText
textSize = 24F
textAlignment = View.TEXT_ALIGNMENT_CENTER
}
},
update = {
it.apply {
text = processedText
}
}
)
}
EmojiCompat 类提供了 process() 方法来将 CharSequences 转换为 Spanned 实例。
可以使用此方法,在后台调用
process()并缓存结果,从而提高应用程序的性能。
5. 问题
-
emoji 图标显示为半透明

这是因为 AppCompatTextView 有一个默认的半透明文本颜色。
上面代码中的
setTextColor(*Black*.*toArgb*())就是为了解决这个问题。 -
无法显示最新的图标
使用了 appcompat 或 emoji2 扩展库后仍然不能显示最新的 emoji 可能的原因:
- 最新的字体文件还未下载成功
- 谷歌的 GMS 服务版本太低
- 系统依赖谷歌的 GMS 服务下载 emoji 字体文件,系统没有 GMS 服务
我们可以考虑使用 emoji2-bundled 扩展库,使用离线的 emoji 字体文件显示,该文件 10M 左右,会增加安装包大小,并且版本发布后用于已经使用的版本不能再次获得最新的字体文件。
emoji2-bundled 的用法与 4. 不使用 EmojiCompat 控件的情况下支持最新的 emoji 章节的用法类似,只是将依赖项 emoji2 改为 emoji2-bundled
// build.gradle implementation 'androidx.emoji2:emoji2-bundled:1.2.0'