Displaying emoticons in Android
Solution 1
I would try using a regular expression to replace all occurrences of each emoticon with an <img>
tag. Then, convert that HTML into a SpannedString
via Html.fromHtml()
. That SpannedString
can be used in a setText()
call on TextView
.
Solution 2
I think it would be more useful to build 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 Html
class.
Edit: Updated version has dramatic speed improvement.
Diepie
Updated on May 07, 2020Comments
-
Diepie about 4 years
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.
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.
Is there an easier and more logical way?
-
Gábor over 9 yearsThe whole internal for cycle and the removal of previous spans doesn't seem to be necessary if, instead of
entry.getValue()
, you useentry.getValue().getConstantState().newDrawable()
to obtain a clone of the drawable for each of its appearance. -
Ravindra Kushwaha almost 7 yearsCan u please help to convert this "5794d5f7895fa10a8f8e1357" into the EMOJI.. Please help me @CommonWare ..Thanks...