36 votes

Affichage des émoticônes dans Android

Mon application de messagerie instantanée doit supporter les émoticônes. Ce sont des GIF et ils ont des représentations textuelles, qui sont utilisées dans le champ de saisie si l'utilisateur en sélectionne un. 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 les images de façon dynamique en fonction de l'occurrence de leur représentation textuelle ? Dois-je rechercher les textes des émoticônes et, si j'en trouve un, supprimer le TextView de la disposition (relativeLayout convient le mieux ?) et ajouter un TextView avec le début de l'IM, un ImageView avec l'émoticône et un autre TextView. Si plusieurs émoticônes sont envoyées simultanément, cela peut être désordonné.

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

120voto

A-IV Points 1315

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

Ce code est basé sur des sources natives Html classe.

Edit : La version mise à jour a considérablement amélioré la vitesse.

39voto

CommonsWare Points 402670

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X