rockerhieu / emojicon

A library to show emoji in TextView, EditText (like WhatsApp) for Android
Apache License 2.0
3.61k stars 818 forks source link

How to calculate each character for emojicon? #65

Closed kirby510 closed 9 years ago

kirby510 commented 9 years ago

Is there any way to calculate the appearance of emojicon in EmojiconTextView accurately? Such as 😎😎😎 is consider as 3 characters.

Thanks in advance for willing to help.

kirby510 commented 9 years ago

I solved this problem, just add these code in the bottom of EmojiconHandler.java

public static int calculateTextLength(Context context, Spannable text, int index, int length, boolean useSystemDefault) { if (useSystemDefault) { return 0; }

    int textCount = 0;
    int textLength = text.length();
    int textLengthToProcessMax = textLength - index;
    int textLengthToProcess = length < 0 || length >= textLengthToProcessMax ? textLength : (length+index);

    // remove spans throughout all text
    EmojiconSpan[] oldSpans = text.getSpans(0, textLength, EmojiconSpan.class);
    for (int i = 0; i < oldSpans.length; i++) {
        text.removeSpan(oldSpans[i]);
    }

    int skip;
    for (int i = index; i < textLengthToProcess; i += skip) {
        textCount++;
        skip = 0;
        int icon = 0;
        char c = text.charAt(i);
        if (isSoftBankEmoji(c)) {
            icon = getSoftbankEmojiResource(c);
            skip = icon == 0 ? 0 : 1;
        }

        if (icon == 0) {
            int unicode = Character.codePointAt(text, i);
            skip = Character.charCount(unicode);

            if (unicode > 0xff) {
                icon = getEmojiResource(context, unicode);
            }

            if (icon == 0 && i + skip < textLengthToProcess) {
                int followUnicode = Character.codePointAt(text, i + skip);
                if (followUnicode == 0x20e3) {
                    int followSkip = Character.charCount(followUnicode);
                    switch (unicode) {
                        case 0x0031:
                            icon = R.drawable.emoji_0031;
                            break;
                        case 0x0032:
                            icon = R.drawable.emoji_0032;
                            break;
                        case 0x0033:
                            icon = R.drawable.emoji_0033;
                            break;
                        case 0x0034:
                            icon = R.drawable.emoji_0034;
                            break;
                        case 0x0035:
                            icon = R.drawable.emoji_0035;
                            break;
                        case 0x0036:
                            icon = R.drawable.emoji_0036;
                            break;
                        case 0x0037:
                            icon = R.drawable.emoji_0037;
                            break;
                        case 0x0038:
                            icon = R.drawable.emoji_0038;
                            break;
                        case 0x0039:
                            icon = R.drawable.emoji_0039;
                            break;
                        case 0x0030:
                            icon = R.drawable.emoji_0030;
                            break;
                        case 0x0023:
                            icon = R.drawable.emoji_0023;
                            break;
                        default:
                            followSkip = 0;
                            break;
                    }
                    skip += followSkip;
                } else {
                    int followSkip = Character.charCount(followUnicode);
                    switch (unicode) {
                        case 0x1f1ef:
                            icon = (followUnicode == 0x1f1f5) ? R.drawable.emoji_1f1ef_1f1f5 : 0;
                            break;
                        case 0x1f1fa:
                            icon = (followUnicode == 0x1f1f8) ? R.drawable.emoji_1f1fa_1f1f8 : 0;
                            break;
                        case 0x1f1eb:
                            icon = (followUnicode == 0x1f1f7) ? R.drawable.emoji_1f1eb_1f1f7 : 0;
                            break;
                        case 0x1f1e9:
                            icon = (followUnicode == 0x1f1ea) ? R.drawable.emoji_1f1e9_1f1ea : 0;
                            break;
                        case 0x1f1ee:
                            icon = (followUnicode == 0x1f1f9) ? R.drawable.emoji_1f1ee_1f1f9 : 0;
                            break;
                        case 0x1f1ec:
                            icon = (followUnicode == 0x1f1e7) ? R.drawable.emoji_1f1ec_1f1e7 : 0;
                            break;
                        case 0x1f1ea:
                            icon = (followUnicode == 0x1f1f8) ? R.drawable.emoji_1f1ea_1f1f8 : 0;
                            break;
                        case 0x1f1f7:
                            icon = (followUnicode == 0x1f1fa) ? R.drawable.emoji_1f1f7_1f1fa : 0;
                            break;
                        case 0x1f1e8:
                            icon = (followUnicode == 0x1f1f3) ? R.drawable.emoji_1f1e8_1f1f3 : 0;
                            break;
                        case 0x1f1f0:
                            icon = (followUnicode == 0x1f1f7) ? R.drawable.emoji_1f1f0_1f1f7 : 0;
                            break;
                        default:
                            followSkip = 0;
                            break;
                    }
                    skip += followSkip;
                }
            }
        }
    }

    return textCount;
}

To call it, int textLength = EmojiconHandler.calculateTextLength(getActivity(), new SpannableStringBuilder(text), 0, -1, false);