首页 > 名字大全 > 微信名字 正文
【微信名字舌头】在网络聊天中解释“Android Emoji”,介绍“EmojiCompat”

时间:2023-04-07 07:55:09 阅读: 评论: 作者:佚名

对应于每个unicode字符的Emoji表情在不同平台上有所不同。因为unicode只规定了Emoji的代码点和意义,没有规定其风格。每个平台都有Emoji实现Emoji表情实践的想法,拿起柚子梗,将选定的表情code放入一个集合中。

然后通过 ViewPager + Fragment + RecyclerView 等一系列控件的配合,实现了 UI 需要的效果

如下图:

从上图可以发现一个问题:有些 Emoji 表情显示出来像一个信封

原因是当前设备不支持,上面我讲到每一个 Unicode 字符对应一个字体,它会被渲染为图片显示,但是如果当前系统不支持这种字体,那么就会显示出一个信封,而且随着 Android 版本越来越低,这种情况越来越多,这种效果肯定是不行的

知道了出现的问题和原因,我们就要去想解决方法,这个时候 EmojiCompat 就来了

EmojiCompat 介绍

什么是 EmojiCompat ?

EmojiCompat 是 Google 官方给我们提供的一个 Emoji 表情兼容库; 最低支持到 Android 4.4(Api Level 19) 的系统设备,它可以防止应用中,出现以信封的形式来显示 Emoji,虽然它仅仅只是因为你当前的设备没有这个字体而已;通过 EmojiCompat ,你的设备无需等待 Android 系统更新,就可以获得最新的 Emoji 表情显示效果

EmojiCompat 的运行原理如下图所示:

从上图我们可以知道:EmojiCompat 会判断当前设备是否支持这个 Emoji,如果支持则还是使用系统内置的字体加载,如果不支持,则使用 EmojiSpan 来进行替换,从而达到替换渲染的效果

如何使用 EmojiCompat ?

要使用 EmojiCompat ,我们需要先对其进行初始化,如下:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n80" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">EmojiCom(config); //EmojiCompat 的 init 方法 public static EmojiCompat init(@NonNull final Config config) { if (sInstance == null) { synchronized (sInstanceLock) { if (sInstance == null) { sInstance = new EmojiCompat(config); } } } return sInstance; }</pre>

上述代码可以看到, EmojiCompat 是一个单例对象,初始化方法就是传入了一个 config 即配置,因此构建配置是 EmojiCompat 初始化能否成功的重点所在,Google 给我们提供了两种配置

他们分别是:

● 可下载的字体配置

● 本地捆绑的字体配置

根据 Google 官方介绍:

● 可下载的字体配置 原理:可下载的字体的方式会在首次启动 app 的时候检查本地是否有该字体,没有的话会从网上下载最新的 Emoji 字体,然后遇到不支持的 Emoji,就会从这个字体文件中,加载资源并且渲染

缺点: 可下载字体的方式,完全依赖 GMS 服务,在没有 GMS 服务的手机上并不可用

● 本地捆绑的字体配置 原理:本地捆绑的方式会在 App 打包的过程中,植入一个最新的 Emoji 字体文件,然后遇到不支持的 Emoji,就会从这个字体文件中,加载资源并且渲染

缺点: 本地捆绑的方式会嵌入一个约 9M+ 的字体文件,无形中增大了 Apk 安装包的体积

EmojiCompat 实践

因为本地捆绑字体配置的方式会使我们的 app 包体积增大 9M+,这是完全不能接受的; 而且我们的 app 主要是面向国外的用户,国外用户手机一般都有 GMS 服务,因此我选用了可下载字体配置来完成 EmojiCompat 的初始化

初始化成功后,我们就可以使用 EmojiCompat 提供的功能了,之前我们是通过如下方式进行表情包加载的:

<pre mdtype="fences" cid="n102" lang="" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//将当前 code 转换为 16 进制数 int hex = In("1F600", 16); //将当前 16 进制数转换成字符数组 char[] chars = C(hex); //将当前字符数组转换成 TextView 可加载的 String 字符串 String mEmojiString = new String(chars);</pre>

现在只需要对当前 mEmojiString 通过 EmojiCompat 处理一下即可,如下:

<pre mdtype="fences" cid="n108" lang="" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//判断当前 EmojiCompat 是否初始化成功 public static boolean isEmojiCompatInit(){ return EmojiCom().getLoadState() == EmojiCom; } //获取可兼容的 emoji 字符串 public static CharSequence getCompatEmojiString(String code) { //将当前 code 转换为 16 进制数 int hex = In(code, 16); //将当前 16 进制数转换成字符数组 char[] chars = C(hex); //将当前字符数组转换成 TextView 可加载的 String 字符串 String mEmojiString = new String(chars); //判断当前系统是否大于等于 19,并且 EmojiCompat 初始化成功 i >= Build.VERSION_CODES.KITKAT && isEmojiCompatInit()){ return EmojiCom().process(mEmojiString); } return mEmojiString; }</pre>

上述代码我们使用 EmojiCompat 的 process 方法对之前的 emoji 字符串做了兼容处理,现在显示出来的表情就不会有啥问题了,这个库使用起来还是很简单的

尾述

私信发送 “底层源码” 即可免费获取 完整代码 以及 更多学习笔记 、 面试视频

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

PS:有问题欢迎指正,可以在评论区留下你的建议和感受; 欢迎大家点赞评论,觉得内容可以的话,可以转发分享一下

  • 评论列表

发表评论: