Android Emoji兼容包使用详解
Emoji兼容性
我们经常会遇到这样的问题: 给朋友发的emoji表情, 在自己手机上展示是正常的, 但是到朋友手机上, 却没有展示出来, 或者展示出来了, 但是也跟自己手机上展示的不一样. 所以, 这是什么原因呢?
要避免这种情况, 就需要使用Android Emoji的兼容包了.
Emoji兼容包目的在于保持Android设备拥有最新的Emoji. 它防止应用使用☐展示丢失的Emoji字符, 而☐意味着设备没有字体支持相应的文本. 通过使用EmojiCompat支持包, 应用的用户不必等候Android系统更新就可以获得最新的Emoji.
EmojiCompat工作原理
EmojiCompat支持包向运行Android 4.4(API 19)+的设备提供类以实现向后兼容的Emoji支持. 你可以配置EmojiCompat使用绑定的或者可下载的字体.
EmojiComat识别指定的CharSequence, 如果必要的话, 会使用EmojiSpans代替它们, 并最终渲染成emoji符号.
可下载字体配置
可下载字体配置使用Downloadable Fonts支持包特性来下载emoji字体. 该支持包也更新必要的emoji元数据, EmojiCompat支持包需要与最新的Unicode版本保持一致.
添加支持包依赖
要使用EmojiCompat支持包, 必要要修改开发环境的应用工程路径依赖.
要在应用中添加支持包, 需要:
- 打开应用build.gradle文件.
- 将依赖包添加到dependencies区域
dependencies { ... compile "com.android.support:support-emoji:27.1.1" }
初始化可下载字体配置
你需要初始化EmojiCompat来下载元数据和字样. 因为初始化会花费一些时间, 所以初始化进程要运行在后台线程.
要初始化EmojiCompat可下载字体配置, 执行以下步骤:
- 创建FontRequest类实例并提供字体提供者权限, 字体提供者包, 字体查询以及认证的hash集列表.
- 创建FontRequestEmojiCompatConfig实例并提供Context实例和FontRequest.
- 调用init()方法初始化EmojiCompat并传递FontRequestEmojiConfig实例
- public class MyActivity extends Activity {
- @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);
- ...
- }
- }
- 在布局文件中使用EmojiCompat控件.
- <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"/>
包构件
构件: EmojiEditText, EmojiTextView, EmojiButton. 这些构件是在TextView, EditText和Button上实现EmojiCompat的默认控件实现.
- EmojiCompat: 支持包的主要公共接口. 它执行了所有的外部调用, 并与系统的其它部分协调.
- EmojiCompat.Config: 配置要创建的单例.
- EmojiSpan: ReplacementSpan子类, 取代字符(序列)并渲染字符.
- EmojiCompat Font: EmojiCompat使用字体展示emoji. 字体是Android Emoji Font的修改版本. 字体接如下规则修改:
- 要提供向后兼容性来渲染emoji, 所有的emoji字符用单个Unicode码点表示, 这个码点位于Unicode Supplement Private Use Area-A, 从U+F001开始的
- 额外的emoji元数据以二进制格式插入字体, 并在运行时被EmojiCompat解析. 这些数据嵌套在字体的meta表中, 并含有私有标签Emji.
配置选项
你能够使用EmojiCompat实例修改EmojiCompat行为. 你可能使用源于基数的如下方法设置配置:
- setReplaceAll(): 决定了EmojiCompat是否应该取代它用EmojiSpans找到的所有emoji. 默认情况下, EmojiCompat尽已所能理解系统是否能够渲染emoji, 但并不取代它们. 设置成true的时候, EmojiCompat会取代它用EmojiSpans找到的所有emoji.
- setEmojiSpanIndicatorEnabled(): 指明EmojiCompat是否用EmojiSpan取代emoji. 设置成true的时候, EmojiCompat为EmojiSpan绘制背景. 但这个方法主要用于debug.
- setEmojiSpanIndicatorColor(): 设置指明EmojiSpan的颜色. 默认值是GREEN.
- registerInitCallback(): 告知应用EmojiCompat初始化的状态.
- 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_SUCCEED或者LOAD_STATE_FAILED.
用AppCompat控件使用EmojiCompat
如果你在使用AppCompat控件, 那么你可能使用继承自AppCompat控件的EmojiCompat控件.
1, 添加如下依赖包.
dependencies { compile "com.android.support:support-emoji-appcompat:$version" }
2, 在布局文件中使用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.
备注: 字体大小有好几MB.
添加支持包依赖
要想使用EmojiCompat支持包的绑定字体配置, 你必须修改开发环境中应用工程的类路径依赖.
dependencies { ... compile "com.android.support:support-emoji-bundled:$version" }
使用绑定字体配置EmojiCompat
要使用绑定字体配置EmojiCompat, 执行下列步骤:
1, 使用BundledEmojiCompatConfig创建EmojiCompat实例并提供Context.
2, 调用init()方法初始化EmojiCompat, 并传入BundledEmojiCompatConfig实例.
- public class MyActivity extends Activity {
- @Override
- public void onCreate() {
- super.onCreate();
- EmojiCompat.Config config = new BundledEmojiCompatConfig(this);
- EmojiCompat.init(config);
- ...
- }
- }
没有控件的情况下使用EmojiCompat
EmojiCompat使用EmojiSpan渲染正确的图片. 由此, EmojiCompat必须使用EmojiSpans将给定CharSequence转化成Spanned. EmojiCompat类提供了方法通过EmojiSpans将CharSequence转化成Spanned对象. 通过这个方法, 你能够处理和缓存已处理实例, 而不是原生字符串, 由此提供了应用的性能.
CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");
IME使用EmojiCompat
使用EmojiCompat支持包, 键盘通过渲染用户正在交互的应用支持的emoji. IME能够使用hasEmojiGlyph()方法检测EmojiCompat是否有能力渲染emoji. 这个方法将一个emoji CharSequence作为形参, 如果EmojiCompat能够检测和渲染这个emoji的话, 会返回true.
键盘也能够检测应用支持的EmojiCompat支持包的版本, 以决定在画板中渲染哪个emoji. 要想检测这个版本, 如果可以的话, 键盘需要检测下列keys是否存在于EditorInfo.extras:
- EDITOR_INFO_METAVERSION_KEY: 如果这个键存在, 这个值表示了应用使用的emoji元数据的版本. 如果这个键不存在, 应用不会使用EmojiCompat.
- EDITOR_INFO_REPLACE_ALL_KEY: 如果该键存在且设置为true, 这表示应用调用了setReplaceAll()方法.
在EditorInfo.extras中接收到键之后, 键盘能够使用hasEmojiGlyph()方法, 在这个方法里面, metadataVersion是键EDITOR_INFO_METAVERSION_KEY的值, 来检测应用是否能够渲染特定的emoji.
在自定义控件中使用EmojiCompat
在应用中, 你总是能够使用process()方法来预处理CharSequence并把它添加到任何能够渲染Spanned实例的控件中. 比如, TextView. 此外, EmojiCompat提供如下控件帮助类让你花费最小的代价就能使用emoji支持丰富自定义控件.
- EmojiTextViewHelper
- EmojiEditTextHelper
Sample TextView:
- 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() {
- ...
- }
- }
Sample EditText:
- 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() {
- ...
- }
- }
QA:
- 我该如何初始化字体下载?
如果Emoji字体在设备上并不存在, 那么在第一次请求的时候就会下载好. 下载调度对于应用是透明的.
- 初始化花费多长时候?
在字体下载好之后, 初始化EmojiCompat大约花费150ms.
- EmojiCompat支持包占用多大内存?
当前, 找到在应用内存中加载好的emoji并使用它的数据结构大约是200KB.
- 自定义TextView可以使用EmojiCompat吗?
是的, EmojiCompat为自定义控件提供帮助类. 它也能够预处理给定字符串并将转换成Spanned.
- 如果我在运行Android 4.4(API 19) - 的设备上, 布局文件中添加了控件, 会发生什么?
你能够在支持Android 4.4(API 19) - 的设备上引入EmojiCompat支持包或者它的控件. 然后, 如果设备运行的Android版本小于API 19, EmojiCompat和它的控件处理"no operation"状态. 这意味着EmojiTextView的行为就是一个常规的TextView. EmojiCompat实例, 在调用init()方法的时候, 马上就会进入LOAD_STATE_SUCCEED状态.
Android Emoji兼容包使用详解的更多相关文章
- 转:android Support 兼容包详解
本文转自stormzhang的ANDROID SUPPORT兼容包详解 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清 ...
- android v7兼容包RecyclerView的使用(四)——点击事件的不同方式处理
前三篇文章 android v7兼容包RecyclerView的使用(三)--布局管理器的使用 android v7兼容包RecyclerView的使用(二) android v7兼容包Recycle ...
- [Android新手区] SQLite 操作详解--SQL语法
该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法 :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...
- Android中Service的使用详解和注意点(LocalService)
Android中Service的使用详解和注意点(LocalService) 原文地址 开始,先稍稍讲一点android中Service的概念和用途吧~ Service分为本地服务(LocalServ ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
- Android 之窗口小部件详解(三) 部分转载
原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...
随机推荐
- docker 从本地拷贝文件
1.找到docker的ID全称 docker inspect -f '{{.Id}}' docker_name 2.执行拷贝命令 docker cp 本地文件路径 ID全称:docker路径 3.如果 ...
- openstack系列文章(一)
学习openstack的系列文章-虚拟化 虚拟化 KVM CPU 虚拟化 KVM 内存虚拟化 全虚拟化 I/O 设备 半虚拟化 I/O 设备 I/O PCI PCIe 设备直接分配 SR-IOV 在 ...
- 根据 WBS 列新 PID 数据
之前写过关于 菜单树的. http://www.cnblogs.com/newsea/archive/2012/08/01/2618731.html 现在在写城市树. 结构: CREATE TABLE ...
- 关于React面试题汇总
1.redux中间件 中间件提供第三方插件的模式,自定义拦截 action -> reducer 的过程.变为 action -> middlewares -> reducer .这 ...
- ubuntu16更新源
http://blog.csdn.net/fengyuzhiren/article/details/54844870
- 【每日scrum】第一次冲刺day5
请教以前做过类似软件的同学,受益匪浅,启发自己
- Java每日学习笔记1
单选按钮 JRadioButton radioButton1 = new JRadioButton("Java");// 创建单选按钮 contentPane.add(radioB ...
- springboot maven
更多信息请从官网获取https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE 1.parent基于自己项目而非spring-boot-starter- ...
- SpringMVC入门学习案例笔记
一.数据库环境用mysql,数据库建表语句如下: /* SQLyog v10.2 MySQL - 5.1.72-community : Database - mybatis ************* ...
- Freemarker中Configuration的setClassForTemplateLoading方法参数问题
今天使用freemarker中Configuration的setClassForTemplateLoading方法遇到了加载模板目录的一个小问题. 由于网上的其他论坛,博客写的有点乱,故记录一下. F ...