1. 程式人生 > >Android字串處理-emoji

Android字串處理-emoji

一、名詞解釋

一個完整的Unicode字元叫程式碼點/CodePoint,而一個Java char 叫程式碼單元code unit;
程式碼點,是從Unicode標準而來的術語,Unicode標準的核心是一個編碼字符集, 它為每一個字元分配一個唯一數字。Unicode標準始終使用16進位制數字,並且在書寫時在前面加上U+, 如字元“A”的編碼為“U+0041”。

程式碼點是指可用於編碼字符集的數字。編碼字符集定義一個有效的程式碼點範圍, 但是並不一定將字元分配給所有這些程式碼點。有效的Unicode程式碼點範圍是U+0000至U+10FFFF。 Unicode4.0將字元分配給一百多萬個程式碼點中的96382個程式碼點。

string物件以UTF-16儲存Unicode字元,需要用2個字元表示一個超大字符集漢字,這種表示方式為 Sruuogate,第一個字元叫Surrogate High,第二個就是Surrogate Low 判斷一個char是否是Surrogate區的字元,用Character的isHighSurrogate()/isLowSurrogate()方法。 從兩個Surrogate High/Low字元,返回一個完整的Unicode CodePoint用Character.toCodePoint()/codePointAt() 一個Code Point,可能需要一個也可能需要兩個char表示,因此不能直接使用CharSequence.length() 方法返回一個字串到底有多少個漢字,而需要用String.codePointCount()/Character.codePointCount()。

二、CodePonits使用

要定位字串中的第N個字元,不能直接將n作為偏移量,而需要從字串頭部依次遍歷得到,需要 String.offsetByCodePoints()。

從字串的當前字元,找到上一個字元,不能直接用offset實現,而需要 String.codePointBefore(),或String.offsetByCodePoints() 。

從當前字元,找下一個字元,需要判斷當前CodePoint的長度,再計算得到 String.offsetByCodePoints()。

codePoint在Textview擷取字串(尤其是emoji表情)時特別有用,

public String ellipsizeText(TextView textView, String text) {
    String tmpTxt = null;
    if (textView != null && text != null) {
        // 為了避免substring刪除emoji等多個char的元素導致的錯誤擷取
        int codePointCount = text.codePointCount(0, text.length());
        for (int i = codePointCount; i >= 0; i--) {
            int offset = text.offsetByCodePoints(0, i);
            if (StringUtil.isEmpty((tmpTxt = text.substring(0, offset)))
                    || (textView.getPaint().measureText(tmpTxt) + textView.getPaddingLeft()
                    + textView.getPaddingRight()) < textView.getWidth()) {
                break;
            }
        }
    }
    return tmpTxt == null ? "" : tmpTxt;
}