web-dev-qa-db-fra.com

Supprimer le soulignement des liens dans TextView - Android

J'utilise deux textview pour afficher les liens de la base de données, j'ai réussi à changer la couleur des liens mais je souhaite supprimer le soulignement

email.setText(c.getString(5));
    website.setText(c.getString(6));
    Linkify.addLinks(email, Linkify.ALL);
    Linkify.addLinks(website, Linkify.ALL);

Puis-je le faire à partir de XML ou de code?

79

Vous pouvez le faire dans le code en recherchant et en remplaçant les instances URLSpan par des versions qui ne sont pas soulignées. Après avoir appelé Linkify.addLinks(), appelez la fonction stripUnderlines() collée ci-dessous sur chacun de vos TextViews:

    private void stripUnderlines(TextView textView) {
        Spannable s = new SpannableString(textView.getText());
        URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
        for (URLSpan span: spans) {
            int start = s.getSpanStart(span);
            int end = s.getSpanEnd(span);
            s.removeSpan(span);
            span = new URLSpanNoUnderline(span.getURL());
            s.setSpan(span, start, end, 0);
        }
        textView.setText(s);
    }

Cela nécessite une version personnalisée de URLSpan qui n'active pas la propriété "underline" de TextPaint:

    private class URLSpanNoUnderline extends URLSpan {
        public URLSpanNoUnderline(String url) {
            super(url);
        }
        @Override public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);
        }
    }
201
Reuben Scratton

Étant donné un textView et le contenu:

TextView textView = (TextView) findViewById(R.id.your_text_view_id);
String content = "your <a href='http://some.url'>html</a> content";

Voici un moyen concis pour supprimer le soulignement des hyperliens:

Spannable s = (Spannable) Html.fromHtml(content);
for (URLSpan u: s.getSpans(0, s.length(), URLSpan.class)) {
    s.setSpan(new UnderlineSpan() {
        public void updateDrawState(TextPaint tp) {
            tp.setUnderlineText(false);
        }
    }, s.getSpanStart(u), s.getSpanEnd(u), 0);
}
textView.setText(s);

Ceci est basé sur l'approche suggérée par robUx4.

Afin de rendre les liens cliquables, vous devez également appeler: 

textView.setMovementMethod(LinkMovementMethod.getInstance());
25
Adriaan Koster

UnderlineSpan existe déjà, mais ne peut définir que le soulignement.

Une autre solution consiste à ajouter une plage sans soulignement sur chaque URLSpan existante. Ainsi, l'état de soulignement est désactivé juste avant de peindre. De cette façon, vous conservez vos classes URLSpan (éventuellement personnalisées) et tous les autres styles définis ailleurs.

public class NoUnderlineSpan extends UnderlineSpan {
    public NoUnderlineSpan() {}

    public NoUnderlineSpan(Parcel src) {}

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
    }
}

Voici comment vous le configurez sans supprimer l'objet URLSpan existant:

URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
for (URLSpan span: spans) {
    int start = s.getSpanStart(span);
    int end = s.getSpanEnd(span);
    NoUnderlineSpan noUnderline = new NoUnderlineSpan();
    s.setSpan(noUnderline, start, end, 0);
}
10
robUx4

A chaque fois, essayez de supprimer les soulignements d'URL avec spannable.

1> Création d'un cours personnalisé:

private class URLSpanNoUnderline extends URLSpan {
            public URLSpanNoUnderline(String url) {
                super(url);
            }
            @Override public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setUnderlineText(false);
            }
        }

Cela nécessite une version personnalisée de URLSpan qui n'active pas la propriété "underline" de TextPaint

2> setSpan avec du texte pouvant être annoncé:

spannableText.setSpan(new URLSpanNoUnderline(UrlText), 0, UrlText.length() , 0);

Ici, spannableText est un objet de SpannableString ... !!!

2
Dhruv Raval

J'ai mis en place une solution qui, à mon avis, est plus élégante. J'ai créé une custom TextView. De cette façon, vous n'avez pas besoin d'exécuter de code supplémentaire pour chaque TextView avec des hyperliens .

package com.example.view;

import Android.content.Context;
import Android.support.v7.widget.AppCompatTextView;
import Android.text.Spannable;
import Android.text.SpannableString;
import Android.text.style.URLSpan;
import Android.util.AttributeSet;

import com.example.utils.UrlSpanNoUnderline;

public class TextViewNoUnderline extends AppCompatTextView {
    public TextViewNoUnderline(Context context) {
        this(context, null);
    }

    public TextViewNoUnderline(Context context, AttributeSet attrs) {
        this(context, attrs, Android.R.attr.textViewStyle);
    }

    public TextViewNoUnderline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setSpannableFactory(Factory.getInstance());
    }

    private static class Factory extends Spannable.Factory {
        private final static Factory sInstance = new Factory();

        public static Factory getInstance() {
            return sInstance;
        }

        @Override
        public Spannable newSpannable(CharSequence source) {
            return new SpannableNoUnderline(source);
        }
    }

    private static class SpannableNoUnderline extends SpannableString {
        public SpannableNoUnderline(CharSequence source) {
            super(source);
        }

        @Override
        public void setSpan(Object what, int start, int end, int flags) {
            if (what instanceof URLSpan) {
                what = new UrlSpanNoUnderline((URLSpan) what);
            }
            super.setSpan(what, start, end, flags);
        }
    }
}

Et le code pour UrlSpanNoUnderline:

package com.jankstudios.smmagazine.utils;

import Android.text.TextPaint;
import Android.text.style.URLSpan;

public class UrlSpanNoUnderline extends URLSpan {
    public UrlSpanNoUnderline(URLSpan src) {
        super(src.getURL());
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
    }
}
2
Sam Sunson

Si vous utilisez la propriété Textview autolink et que vous souhaitez supprimer le soulignement, vous pouvez l'utiliser:

Tout d’abord, étendez UnderlineSpan et supprimez le soulignement:

public class NoUnderlineSpan extends UnderlineSpan {

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
    }
}

Deuxièmement, créez une instance de NoUnderlineSpan, créez un élément Spannable à partir du texte String et définissez l'étendue sur spannable:

NoUnderlineSpan mNoUnderlineSpan = new NoUnderline();
if (yourTextView.getText() instanceof Spannable) {
    Spannable s = (Spannable) yourTextView.getText();
    s.setSpan(mNoUnderlineSpan, 0, s.length(), Spanned.SPAN_MARK_MARK);
}

Référence: http://prog3.com/sbdm/blog/maosidiaoxian/article/details/39156563

1
Francisco Moya

Voici ma méthode 

 public static void removeUnderlines(Spannable p_Text) {
            if (p_Text != null && p_Text.toString().length() > 0) {
                URLSpan[] spans = p_Text.getSpans(0, p_Text.length(), URLSpan.class);

                for (URLSpan span : spans) {
                    int start = p_Text.getSpanStart(span);
                    int end = p_Text.getSpanEnd(span);
                    p_Text.removeSpan(span);
                    span = new URLSpanNoUnderline(span.getURL());
                    p_Text.setSpan(span, start, end, 0);
                }
            }
        }

Appelle-le comme ça 

AppController.removeUnderlines((Spannable) eventEmail.getText());

Appcontroller est ma classe d'application où je mets cette méthode pour pouvoir y accéder de n'importe où

0
Bharat singh

Si vous voulez juste le texte et ne vous souciez pas du lien URL 

Ceci va STRIP le lien mais GARDER le texte

private Spannable stripLinks(String content) {
    Spannable s = new SpannableString(content);
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan span : spans) {
        s.removeSpan(span);
    }

    return s;
}

aucun cours supplémentaire requis

String content = "<a href='http://stackoverflow.com'>Stack Overflow</a> Rocks!";
textView.setText(stripLinks(content));
0
Samuel

Pour les utilisateurs de Xamarin ayant trouvé ce message, voici comment je l’ai fait fonctionner:

  1. Créez une classe étendue personnalisée pour gérer la suppression des soulignements.

    classe URLSpanNoUnderline: URLSpan { public URLSpanNoUnderline (string url): base (url) { }

        public override void UpdateDrawState (TextPaint ds) {
            base.UpdateDrawState (ds);
            ds.UnderlineText = false;
        }
    }
    
  2. Créez une méthode d'extension pour rechercher toutes les étendues d'URL et remplacez-les par nos étendues personnalisées.

    public static void StripUnderlinesFromLinks (this TextView textView) { var spannable = new SpannableStringBuilder (textView.TextFormatted); var spans = spannable.GetSpans (0, spannable.Length (), Java.Lang.Class.FromType (typeof (URLSpan)));. foreach (URLSpan span in span) { var start = spannable.GetSpanStart (span); var end = spannable.GetSpanEnd (span); spannable.RemoveSpan (span); var newSpan = new URLSpanNoUnderline (span.URL); spannable.SetSpan (newSpan, start, end, 0); } textView.TextFormatted = spannable; }

0
Justin