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;
}

猜你喜欢

转载自blog.csdn.net/sinat_28496853/article/details/86366186