1. 程式人生 > >Android中Emoji的處理

Android中Emoji的處理

一、Emoji的前世今生

1、Emoji的誕生

Emoji表情是一種視覺上的速記符號,最初是在1999年由一個名叫Shigetaka Kurita(慄田穣崇)的日本人發明的。
而後隨著發展,出現了統一碼聯盟(The Unicode Consortium),它的主要工作就是統籌統一碼(Unicode)的發展。

作為一種字元編碼,Unicode的出現主要是為了解決現存編碼不能夠在多語言電腦環境中使用的問題。Unicode對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字,這當然也包括Emoji。

The Unicode Consortium 會按照一定的節奏來更新 Unicode 的標準,目前最新的標準是今年釋出的Unicode 9.0。

當我們發現某個非常喜歡的動作或物品時,而它又沒有出現在現有的Emoji庫中,那我們可以到Unicode官網或通過The Unicode Consortium的成員去提交這個Emoji;接著,The Unicode Consortium的Emoji小組委員會會根據一系列的標準來討論並評審這個Emoji,以決定它適不適合被選中。

當一個Emoji通過The Unicode Consortium的評審成為標準之後,它還只是停留在檔案上,還需要系統開發商(比如蘋果、Google等)在系統字型層面進行支援才行。

2、世界Emoji日

每年的7月17日是世界Emoji日。

二、Emoji表情怎麼建立的?

emoji就是一組Unicode編碼與一組表情描述之間的一一對應。而圖片的實現是由各個系統或者軟體針對統一的表情描述來各自實現的,他們都遵循統一的Unicode編碼規範。也就是說Unicode編碼其所對應的表情描述是統一的,是所有人都要共同遵守的一套標準或者規範,而具體的表情圖片則可能因平臺的不同而產生差異,比如Android和IOS。

對於Unicode編碼為”U+1F602”的表情,各個平臺分別做了不同的實現。

三、Emoji在Android中的使用

對於一般使用者來說,我們可以通過安裝第三方輸入法來進行Emoji表情的輸入,但對於我們寫程式的人來說,總不能這樣吧。

So,既然Emoji表情是通過Unicode編碼實現的,那我們就可以使用Character.toChars()方法將Unicode編碼轉換為一個char陣列,再將這個char陣列轉換為字串就可以直接操作了,作業系統會自行將其解析為表情圖片的,然後顯示在文字元件中。

程式碼實現:

private void setEmojiToTextView(){
    int unicodeJoy = 0x1F602;
    String emojiString = getEmojiStringByUnicode(unicodeJoy);
    myTextView.setText(emojiString);
}

private String getEmojiStringByUnicode(int unicode){
    return new String(Character.toChars(unicode));
}

當然,這只是其中的一種方法,我們還可以通過Emoji字型庫來實現效果,將製作好Emoji字型庫拷貝到Android工程的assets/fonts目錄,然後程式碼中進行處理:

try {
    Typeface typeFace = Typeface.createFromAsset(getResources().getAssets(),"fonts/AndroidEmoji.ttf");
        title.setTypeface(typeFace);
} catch (Exception e) {
        Logger.e(e);
}

之後,當我們在該title控制元件上輸入Emoji表情的Unicode後會自動轉換為表情圖片。

對於早期的Android系統(Android 4.1之前)而言,它本身並不支援Emoji的顯示,這種情況下我們可以實現一個表情管理類,然後使用Emoji圖片來進行顯示。

若是要顯示全域性彩色的Emoji,我們可以編寫一個全域性顯示Emoji的類來繼承TextView或EditText,這樣方便管理,當然,這麼好東西網上早就有了,請移步Emoji庫:https://github.com/rockerhieu/emojicon,基本上可以覆蓋常用的操作了。

最後在專案開發中,尤其是聊天應用開發中,我們通常需要做的是把訊息中含有的unified的emoji編碼過濾出來,然後映射出對應的表情資源,並顯示出來。傳送Emoji時也是一樣,先找到對應的Unicode碼,再傳送過去。

還有需要注意的是,Android端和IOS端的表情顯示預設是不一樣的,所以為了達到體驗的一致,Android和IOS應該通用一套同樣的Emoji表情圖片。再者,對於不在自己程式碼定義的範圍內的emoji需要過濾掉,類似微信的做法。

最後,在Android的聊天頁面進行Emoji表情的選擇時,我們也需要注意:

emoji庫是通過不斷對比map裡面的資料來查詢的,會導致在列表中過多的Emoji滾動時會很卡。解決辦法是:在得到列表json資料的時候,在對映的時候就轉碼成emoji,並將該emoji直接放入實體。這樣就避免了滾動list的時候轉碼帶來的卡頓!

在輸入emoji的地方(發表內容),連續輸入多個emoji會卡頓甚至卡死,原因同上,因為這個庫是對比查詢的,預設的演算法是假如有1000個emoji,那麼就1個emoji的key對比1000次,而輸入的時候由於每次輸入都進行了轉碼,所以輸入一個emoji就要對整段text進行emoji對比。效能嚴重下滑!解決辦法是改變自己的演算法,只轉碼新輸入的那個字元。

參考文件: