在 Android 中显示表情符号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3341702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:48:40  来源:igfitidea点击:

Displaying emoticons in Android

androiddynamicimageviewemoticons

提问by Diepie

My IM app has to support emoticons. They are GIFs and have textual representations, which are used in the input box if the user selects one of them. But I'd like to display them as images after they have been sent.Currently my custom array adapter displays the sent message in a TextView of a row.

我的 IM 应用程序必须支持表情符号。它们是 GIF 并具有文本表示,如果用户选择其中之一,则会在输入框中使用。但是我想在发送后将它们显示为图像。目前我的自定义数组适配器在一行的 TextView 中显示发送的消息。

What is the proper method to display images dynamically based on the occurrence of their textual representation? Do I have to search for emoticon texts, and if one found, remove the TextView from the layout (relativeLayout fits most?) and add a TextView with the beginning of the IM, an ImageView with the emoticon and another TextView. If more emoticons sent simultaneously it can be messy.

根据文本表示的出现动态显示图像的正确方法是什么?我是否必须搜索表情文本,如果找到,从布局中删除 TextView(relativeLayout 最适合?)并添加一个带有 IM 开头的 TextView、一个带有表情的 ImageView 和另一个 TextView。如果同时发送更多表情符号,则可能会很混乱。

Is there an easier and more logical way?

有没有更简单、更合乎逻辑的方法?

回答by A-IV

I think it would be more useful to build Spannable.

我认为构建Spannable.

private static final Factory spannableFactory = Spannable.Factory
        .getInstance();

private static final Map<Pattern, Integer> emoticons = new HashMap<Pattern, Integer>();

static {
    addPattern(emoticons, ":)", R.drawable.emo_im_happy);
    addPattern(emoticons, ":-)", R.drawable.emo_im_happy);
    // ...
}

private static void addPattern(Map<Pattern, Integer> map, String smile,
        int resource) {
    map.put(Pattern.compile(Pattern.quote(smile)), resource);
}

public static boolean addSmiles(Context context, Spannable spannable) {
    boolean hasChanges = false;
    for (Entry<Pattern, Integer> entry : emoticons.entrySet()) {
        Matcher matcher = entry.getKey().matcher(spannable);
        while (matcher.find()) {
            boolean set = true;
            for (ImageSpan span : spannable.getSpans(matcher.start(),
                    matcher.end(), ImageSpan.class))
                if (spannable.getSpanStart(span) >= matcher.start()
                        && spannable.getSpanEnd(span) <= matcher.end())
                    spannable.removeSpan(span);
                else {
                    set = false;
                    break;
                }
            if (set) {
                hasChanges = true;
                spannable.setSpan(new ImageSpan(context, entry.getValue()),
                        matcher.start(), matcher.end(),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
    }
    return hasChanges;
}

public static Spannable getSmiledText(Context context, CharSequence text) {
    Spannable spannable = spannableFactory.newSpannable(text);
    addSmiles(context, spannable);
    return spannable;
}

Actualy this code based on sources from native Htmlclass.

实际上,此代码基于本机Html类的来源。

Edit: Updated version has dramatic speed improvement.

编辑:更新版本有显着的速度提升。

回答by CommonsWare

I would try using a regular expression to replace all occurrences of each emoticon with an <img>tag. Then, convert that HTML into a SpannedStringvia Html.fromHtml(). That SpannedStringcan be used in a setText()call on TextView.

我会尝试使用正则表达式用<img>标签替换每个表情符号的所有出现。然后,将该 HTML 转换为SpannedStringviaHtml.fromHtml()。这SpannedString可以用于setText()调用TextView.