什么是 emoji铐然?
emoji 是一種 表情符號(hào)晌缘,來(lái)自日語(yǔ)詞匯“絵文字”(假名為“えもじ”纠永,讀音即 emoji)
它的創(chuàng)造者是日本人栗田穰崇 ( Shigetaka Kurita ) 领跛,他將目光投向兒時(shí)的各種元素以獲取靈感,如日本漫畫(huà)和日本漢字等叔收〕菟耄“日本漫畫(huà)中有許多不同的符號(hào)。漫畫(huà)家會(huì)畫(huà)出一些表情饺律,表現(xiàn)一個(gè)人滿頭大汗或是迸發(fā)出一個(gè)想法時(shí)頭上出現(xiàn)一個(gè)燈泡窃页。”同時(shí)复濒,從日本漢字中他獲得了一種能力脖卖,用簡(jiǎn)單的字符來(lái)表達(dá)“秘密”和“愛(ài)”等抽象概念。
早期的 emoji 表情并沒(méi)有一套統(tǒng)一的規(guī)范芝薇,日本的三大電信運(yùn)營(yíng)商胚嘲,NTT DoCoMo作儿,au/KDDI洛二,Softbank 都各自有一套關(guān)于 Emoji 的編碼規(guī)范,導(dǎo)致運(yùn)營(yíng)商用戶之間發(fā)送 emoji 表情時(shí)無(wú)法顯示攻锰。
直到2010年10月晾嘶,隨著 Unicode6.0 的發(fā)布,Emoji 的編碼以及對(duì)應(yīng)的表情圖片正式被規(guī)范化娶吞,核心 Emoji 表情包含722個(gè) Emoji 編碼垒迂。
之后 2014年6月15日發(fā)布的 Unicode 7.0 規(guī)范以及 2016年6月22日發(fā)布的 Unicode 9 規(guī)范都不斷地加入新的 emoji 表情,目前整個(gè) emoji 表情已經(jīng)達(dá)到了一千多個(gè)妒蛇。
感興趣的同學(xué)可以到這里查看所有表情對(duì)應(yīng)的編碼
Android 對(duì) emoji 表情的兼容
很多同學(xué)可能并沒(méi)有注意到 Android 設(shè)備上的 Emoji 表情
一般情況下机断,我們?cè)谑謾C(jī)上進(jìn)行操作時(shí)楷拳, 只有使用了輸入法自帶的表情及 emoji 表情才會(huì)在文本中產(chǎn)生 emoji 編碼。
在 Android 4.4 之前吏奸, Android 并不支持 emoji 表情欢揖,當(dāng)時(shí)的解決方案主要是通過(guò) imageSpan 配合 spannableString,來(lái)替換掉文字中的 emoji unicode 編碼符號(hào)奋蔚。
從 Android 4.4 開(kāi)始她混, 官方開(kāi)始了 emoji 表情的支持,實(shí)現(xiàn)原理基本就是通過(guò)把 emoji 表情內(nèi)置在系統(tǒng)的 ttf 字體庫(kù)中泊碑,對(duì)文本進(jìn)行過(guò)濾后顯示出 emoji 表情坤按。
由于不同 Android 版本內(nèi)置的 ttf 字體庫(kù)對(duì) emoji 表情的版本支持程度不同,導(dǎo)致老版本的 Android 對(duì)最新的 emoji 表情支持不全馒过,所以一些 在新的 unicode 版本規(guī)范中被加入的 emoji 表情在老的 Android 設(shè)備上會(huì)顯示方框亂碼臭脓。
為了處理這個(gè)問(wèn)題,除去上文提到的 spannable 的處理方案腹忽,我們還可以通過(guò)定義自己的 ttf 字體庫(kù)給文本空間指定字體來(lái)顯示 emoji 表情谢鹊。
EmojiCompat Support Library 的誕生
正是由于上文提到的兼容問(wèn)題,Google 官方的 EmojiCompat Support Library 誕生了留凭。
目前這個(gè)庫(kù)能向下兼容到 Android 4.4佃扼,其主要目標(biāo)就是為了讓我們的 Android 設(shè)備能夠支持最新的 emoji 表情,防止最新的 emoji 表情在我們的手機(jī)上顯示為?蔼夜。
EmojiCompat 通過(guò) CharSequence 文本中的 emoji 對(duì)應(yīng)的 unicode 編碼來(lái)識(shí)別 emoji 表情兼耀,將他們替換成 EmojiSpans ,最后再將 EmojiSpan 渲染成對(duì)應(yīng)的 emoji 表情符號(hào)求冷。
對(duì)于 EmojiCompat 的使用瘤运,有兩種配置方式:
Downloadable fonts configuration
Downloadable fonts 是 Android O 新增的一個(gè)功能,支持通過(guò) google mobile service 遠(yuǎn)程拉取需要的字體庫(kù)到本地來(lái)進(jìn)行使用匠题。
由于國(guó)內(nèi)屏蔽了 Google Service 拯坟,所以這種方式在國(guó)內(nèi)我們使用不了,這里我們就不做詳細(xì)介紹了韭山。
Bundled fonts configuration
Bundled fonts 即打包字體郁季,就是使用本地打包好的 emoji 字體庫(kù)來(lái)兼容 emoji 表情。
目前官方使用的是 NotoColorEmojiCompat.ttf
字體文件钱磅。
EmojiCompat 的使用
接下來(lái)我們來(lái)看看如何使用 emojiCompat 庫(kù)
添加依賴庫(kù)
首先我們?cè)?build.gradle 中配置我們的依賴包梦裂,由于我們使用的是 Bundled fonts 的配置,所以我們需要先引入我們的 emoji bundle 庫(kù):
dependencies {
...
compile "com.android.support:support-emoji-bundled:$version"
}
這里我 $version 設(shè)置的版本是 26.0.0-beta1盖淡,如果編譯過(guò)程中提示找不到依賴庫(kù)年柠,需要在 repositories 倉(cāng)庫(kù)配置中加入 Google 的 maven 地址:
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}
接著我們引入 EmojiCompat 的組件庫(kù):
dependencies {
...
compile "com.android.support:support-emoji:26.0.0-beta1"
}
該組件庫(kù)對(duì)應(yīng)的 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"/>
如果你使用的是 AppCompat 庫(kù), 也可以直接添加 emojiCompat 的 compat 組件庫(kù)
dependencies {
compile "com.android.support:support-emoji-appcompat:26.0.0-beta1"
}
該引用庫(kù)對(duì)應(yīng)的組件:
<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"/>
compat 庫(kù)跟非 compat 庫(kù)之間的差別主要就是在使用的組件名稱上褪迟,其他的方式基本一致冗恨。
初始化 EmojiCompat
在正式使用 EmojiCompat 之前我們還需要對(duì)其進(jìn)行初始化
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
EmojiCompat.Config config = new BundledEmojiCompatConfig(this);
EmojiCompat.init(config);
}
}
此時(shí)我們便可以使用上一步添加的 emojiCompat 組件來(lái)替換原有的 TextView答憔、 EditText 以及 Button 組件了,當(dāng)文本中遇到對(duì)應(yīng)的 emoji 表情編碼時(shí)就會(huì)自動(dòng)替換為 emoji 表情了掀抹。
不通過(guò)組件使用 emojiCompat 兼容庫(kù)
EmojiCompat 庫(kù)通過(guò) EmojiSpan 來(lái)渲染正確的表情圖片攀唯,因此需要先將文本 CharSequence 根據(jù) emoji 編碼轉(zhuǎn)換成對(duì)應(yīng)的 EmojiSpan Spanned 實(shí)例。
EmojiCompat 專門提供了一個(gè) process() 方法用于CHarSequence 實(shí)例的轉(zhuǎn)換
使用這種方法渴丸,我們可以緩存處理過(guò)的實(shí)例而不是原始字符串侯嘀,在需要使用的地方直接調(diào)用該實(shí)例,從而提高應(yīng)用程序的性能谱轨。
TextView regularTextView = findViewById(R.id.regular_text_view);
CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");
regularTextView.setText(processed);
自定義 EmojiCompat 組件
除了上面提到的通過(guò) EmojiCompat 的 process 方法轉(zhuǎn)換 spanned 實(shí)例外戒幔,我們還可以通過(guò)官方提供的兩個(gè) widget helper 類來(lái)自定義我們的 TextView 以及 EditTextView 組件:
android.support.text.emoji.widget.EmojiTextViewHelper
android.support.text.emoji.widget.EmojiEditTextHelper
示例代碼:
自定義Emoji 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() {
...
}
}
自定義 Emoji 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() {
...
}
}
總結(jié)
看了上面的使用步驟,EmojiCompat 的使用是不是很方便呢土童?
目前來(lái)說(shuō)诗茎,EmojiCompat 只兼容 Android 4.4 以上的設(shè)備,對(duì)于 4.4 以下的設(shè)備献汗,它的行為跟普通的 Android 組件沒(méi)有差異敢订。
EmojiCompat 的初始化時(shí)間大約只需要 150 毫秒,內(nèi)存的占用大概在200kb罢吃,所以你可以放心大膽地去使用它楚午。
這里是官方的 Demo 地址:
https://github.com/googlesamples/android-EmojiCompat
里面包含了 downloadable fonts 的使用,因?yàn)楸容^完善 尿招,所以就不放我自己的 Demo 啦矾柜,感興趣的小伙伴趕緊去下載看看吧!