web-dev-qa-db-fra.com

Affichage des émoticônes dans Android

Mon application de messagerie instantanée doit prendre en charge les émoticônes. Ce sont des GIF et ont des représentations textuelles, qui sont utilisées dans la zone de saisie si l'utilisateur en sélectionne une. Mais je voudrais les afficher sous forme d'images après leur envoi. Actuellement, mon adaptateur de tableau personnalisé affiche le message envoyé dans une TextView d'une ligne.

Quelle est la méthode appropriée pour afficher des images de manière dynamique en fonction de l'occurrence de leur représentation textuelle? Dois-je rechercher des textes d'émoticônes et, le cas échéant, supprimer TextView de la mise en page (relativeLayout convient le mieux?) Et ajouter une TextView avec le début de la messagerie instantanée, une ImageView avec l'émoticône et une autre TextView. Si plusieurs émoticônes sont envoyées simultanément, cela peut être compliqué.

Existe-t-il un moyen plus simple et plus logique?

36
Diepie

J'essaierais d'utiliser une expression régulière pour remplacer toutes les occurrences de chaque émoticône par une balise <img>. Ensuite, convertissez ce code HTML en SpannedStringvia Html.fromHtml() . Ce SpannedString peut être utilisé dans un appel à setText() sur TextView.

39
CommonsWare

Je pense qu'il serait plus utile de construire 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;
}

Actuellement, ce code est basé sur les sources de la classe native Html.

Edit: la version mise à jour a une amélioration spectaculaire de la vitesse.

120
A-IV