查看原文
其他

让您的应用支持新式的 Emoji 符号吧!

Android Android 开发者 2022-05-12

Emoji 已无处不在,自发布以来 emoji 已成为我们语言中不可或缺的一部分,它生动有效的表达力带来了语言文字层面的变革。您可能不会想到,连银行应用、健身应用或外卖应用也都应该支持 emoji。Emoji 现在已经遍布短信等通讯应用,已经成为我们语言的一部分。如果您的应用包含文本视图,那么它应该支持 emoji,至于原因,且听我娓娓道来。🥳


遇到的问题 😖



如果您的应用没有对 emoji 进行相应的处理,较早版本的 Android 可能不知道如何去显示它们。在大多数情况下,只会显示一个空白方格,我们称之为 "豆腐"。在未正确处理 emoji 的应用中,在原本应该显示 emoji 的位置将会显示出一个 "豆腐块",这可能会给用户带来困惑。例如,如果用户在 TODO 应用的任务列表里,向 EditText 中添加一个 🐶 表情,此时用户看到 "豆腐" 出现在屏幕上而没有显示输入的 🐶 表情时,用户则会认为应用存在 bug。

为了使 emoji 更加有趣,在很多情况下,一个 emoji 是由其它多个 emoji 组成的。比如 💪🏾 是 💪 和 🟫 的组合。


如果您输入肌肉的表情,而应用显示了胳膊和颜色方块,那么就不仅会让用户感到困惑,同时对于不同肤色风格的表述也有失准确,从而降低了应用的用户体验。


随着语言的发展,emoji 也在不断进化。每年新的 emoji 会以 Unicode 的形式添加到新的 Android 发行版本中,但可惜的是,没有途径能够将新的 emoji 字体添加到 Android S 之前的版本。



解决方案



emoji2 库已经集成到了 AppCompat 1.4,这意味着您只需升级至 AppCompat 1.4 版本,便可在 API 19 及更高版本上显示流行的 emoji。AppCompat 中的所有 TextView 都默认支持,因为我们添加了自动配置,所以它可以配置自己来加载正确的 emoji 字体。如果需要,您可以在 XML 或者代码中为特定的 TextView 关闭该功能。


  • emoji2
    https://developer.android.google.cn/jetpack/androidx/releases/emoji2


我们来看一下在 AppCompat 1.3 和 AppCompat 1.4 中 emoji 的显示有什么区别。

简单来说,图形化的 emoji 实际上只是显示在文本中的一个图片 🖼️ 。它通过 Unicode 码点来表示,如同字母 'e',但是 Unicode 规定: 当显示码点时,应显示 emoji 图片而非字母 'e'。这张图片仅是字体文件中的一个 png (更多内容请参阅我们为 Android 打造的 emoji 字体)。通常您可能认为字体内容就是字母 'e' 的笔画定义,但实际上字体的功能非常强大,可以包含 bitmap、png、svg,甚至完整的程序——有人在字体中实现了一个游戏 🤯。


  • 为 Android 打造的 emoji 字体
    https://github.com/googlefonts/noto-emoji

  • 游戏
    https://www.coderelay.io/fontemon.html#player


当以 Unicode 添加新的 emoji 时,新的 emoji 需要将新的字形或者可打印字符添加到 emoji 字体中——然后更新相应的表,字体就知道通过哪个码点来显示这个字形。

当输入字符串到平台时,EmojiCompat.process 需要将它进行转换,使其包含 EmojiSpan,它会告诉 Android 系统不要将该部分作为字符串显示,EmojiSpan 知道如何显示 emoji。


  • 字形
    https://en.wikipedia.org/wiki/Glyph

  • EmojiSpan
    https://developer.android.google.cn/reference/androidx/emoji/text/EmojiSpan


EmojiCompat.process 会遍历字符串并且找到所有的 emoji,并为每个 emoji 添加 EmojiSpan。EmojiSpan 会告诉 Android 不要以字符串的形式显示,而是调用 draw 方法来显示。EmojiCompat.process 使用字典树来查找所有的子字符串来匹配一个已知的 emoji。

  • EmojiCompat.process
    https://developer.android.google.cn/reference/androidx/emoji/text/EmojiCompat#process(java.lang.CharSequence,%20int,%20int,%20int,%20int)


字典树是一种非常有趣的数据结构,它非常适合在字典中高效地查找单词 (或者 emoji)。EmojiCompat 会遍历字符串,针对字典树检查每个码点。一旦它在字典树中找到完整的 emoji,它会检查是否平台不清楚如何显示 emoji 并且添加 EmojiSpan。您可以理解为 EmojiCompat 就是使用字典在字符串中寻找 emoji,而对应字典内容的定义就是如何使用 EmojiSpan 来显示所需的 emoji。

现在我们知道了 EmojiCompat 如何获取 emoji,接下来我们聊聊如何显示字符串 "Hi"。

一个字符串就是一组码点,它们通过数字来表示字形,比如字母 'm' 或者数字 '1'。Emoji 同样有对应的码点——您可以在 Emojipedia 上找到它们,包括我们现在要显示的挥手 emoji

  • Emojipedia
    https://emojipedia.org/

  • 挥手 emoji
    https://emojipedia.org/waving-hand/


最后,draw 函数会被调用,然后将字体文件中的 emoji 直接画出来,并且包含您想要的效果——您的字符串!🥳🥳🥳

最后



Emoji 不仅仅只是有趣,它已经成为我们语言中不可或缺的一部分。如果您准备为用户提供支持流行 emoji 的最佳体验,请使用 AppCompat 1.4。
 
继续前进,继续使用 emoji 啦~ 🥳 🦄
 
更多关于 emoji 的最新 Play 政策,请参阅: 

https://support.google.com/googleplay/android-developer/answer/11190649?hl=zh-cn


您也可以通过下方二维码向我们提交反馈,或分享您喜欢的内容、发现的问题。您的反馈对我们非常重要,感谢您的支持!



推荐阅读

如页面未加载,请刷新重试

 点击屏末 | 阅读原文 | 即刻了解新式表情符号更多内容



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存