TextView - Android में लिंक से अंडरलाइन निकालें


93

मैं textviewडेटाबेस से लिंक प्रदर्शित करने के लिए दो का उपयोग कर रहा हूं, मैं लिंक रंग बदलने में कामयाब रहा लेकिन मैं अंडरलाइन को हटाना चाहता हूं

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

क्या मैं XML या कोड से ऐसा कर सकता हूं?

जवाबों:


220

आप इसे उन URLSpanसंस्करणों को खोजने और बदलने के द्वारा कोड में कर सकते हैं जो रेखांकित नहीं करते हैं। कॉल करने के बाद Linkify.addLinks(), stripUnderlines()अपने प्रत्येक 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);
    }

इसके लिए URLSpan के एक अनुकूलित संस्करण की आवश्यकता होती है जो TextPaint की "अंडरलाइन" संपत्ति को सक्षम नहीं करता है:

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

9
यह समाधान मानता है कि स्पैन का पाठ URL के समान है, जो मूल http: // लिंक के मामले में है। हालाँकि, Linkify स्मार्ट है और URL में फोन नंबर (212) 555-1212 की तरह कनवर्ट करता है tel:2125551212new URLSpanNoUnderlineकॉल पारित किया जाना चाहिए span.getURL()यह जानकारी बनाए रखने के लिए, अन्यथा आप जब क्लिक कि कारण अपवाद बुरा लिंक उत्पन्न करते हैं। मैंने आपके उत्तर के लिए संपादन कतार में इस प्रस्तावित समाधान को रखा है, क्योंकि मेरे पास स्वयं संपादन की अनुमति नहीं है।
माइक मुलर

8
मेरे लिए काम नहीं कर रहा। यह लाइन स्पैनेबल s = (Spannable) textView.getText () में क्लास कास्ट एक्सेप्शन देता है;
बृजेश ठाकुर

5
बस उस लाइन को Spannable s = new SpannableString (textView.getText ()) से बदल दें;
फ़्लिवेइरा

1
साथ की जगह Spannable s = (Spannable) textView.getText()के साथ Spannable s = new SpannableString(textView.getText());मेरे लिए काम नहीं करता। अगर मैं कास्टिंग पर वापस जाता हूं तो यह काम करता है, केवल अगर TextView है android:textIsSelectable=true। कोई विचार क्यों?
shoke

2
क्या इस कार्य को android:autoLinkविशेषता के साथ करने का कोई तरीका है ? अन्यथा ऐसा लगता है कि आपको कार्यक्षमता में निर्मित के लिए अपने स्वयं के ऑनक्लिक तरीकों का निर्माण करना होगा।
अल्करिन

32

एक textView और सामग्री को देखते हुए:

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

हाइपरलिंक से अंडरलाइन को हटाने का एक संक्षिप्त तरीका यहां दिया गया है:

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

यह robUx4 द्वारा सुझाए गए दृष्टिकोण पर आधारित है।

लिंक को क्लिक करने योग्य बनाने के लिए आपको कॉल करने की भी आवश्यकता है:

textView.setMovementMethod(LinkMovementMethod.getInstance());

7
यदि आप संसाधनों से स्ट्रिंग प्राप्त करने का प्रयास करते हैं तो यह काम नहीं करता है, इसलिए String content = getResources().getString(R.string.content);इसमें एक लिंक शामिल है जो अब काम नहीं करता है।
रेन मैन

1
ऐसे कैसे हो सकता है? एक स्ट्रिंग को यह नहीं पता है कि यह कहां से उत्पन्न हुआ है। स्ट्रिंग सामग्री में अंतर होना चाहिए।
एड्रियन कोस्टर

यकीन नहीं क्यों, लेकिन यह यूआरएल नहीं दिखाता है जब मैं स्ट्रिंग को कॉल करता हूं res/values/strings.xmlजिसमें उदाहरण के रूप में बिल्कुल वैसा ही होता है। क्या आप अपने अंत में परीक्षण कर सकते हैं?
रेन मैन

मैं निश्चित रूप से अपने अंत में परीक्षण नहीं करने जा रहा हूं (-: यदि आप स्ट्रिंग सामग्री के बारे में सुनिश्चित होना चाहते हैं, तो दोनों स्ट्रिंग्स को अपने हैशकोड के साथ एक साथ लॉग इन करें। ऊपर कोड का उपयोग करते समय अलग-अलग परिणाम मिलने पर मुझे आश्चर्य होगा। ठीक इसी तरह के तार।
एड्रियन कोस्टर

1
यदि आप इसे संसाधनों से स्ट्रिंग प्राप्त करने के साथ काम करना चाहते हैं, तो आपको इसे एन्कोड करने की आवश्यकता है। उदाहरण के लिए = >= &gt;, आदि: डेवलपर देखें <&lt;<string name="link_to_google" >&lt;a href="https://www.google.com/"&gt;Google&lt;/a&gt;</string>
।android.com

11

UnderlineSpan पहले से मौजूद है, लेकिन केवल रेखांकन सेट कर सकता है।

एक अन्य समाधान यह है कि प्रत्येक मौजूदा पर नो अंडरलाइन स्पैन को जोड़ा जाए URLSpan। इस प्रकार पेंटिंग के ठीक पहले अंडरलाइन अवस्था अक्षम हो जाती है। इस तरह से आप अपनी URLSpan(संभवतः कस्टम) कक्षाएं और अन्य सभी शैलियों को कहीं और सेट करते हैं।

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

    public NoUnderlineSpan(Parcel src) {}

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

यहां बताया गया है कि आपने मौजूदा URLSpan ऑब्जेक्ट को हटाए बिना इसे कैसे सेट किया है:

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

3

मैंने एक समाधान लागू किया है, जो मेरी राय में, अधिक सुरुचिपूर्ण है। मैंने एक रिवाजTextView बनाया है । इस तरह आपको TextViewहाइपरलिंक्स के लिए अतिरिक्त कोड निष्पादित करने की आवश्यकता नहीं है ।

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

और 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);
    }
}

3

यहाँ कोटलिन विस्तार समारोह है:

fun TextView.removeLinksUnderline() {
    val spannable = SpannableString(text)
    for (u in spannable.getSpans(0, spannable.length, URLSpan::class.java)) {
        spannable.setSpan(object : URLSpan(u.url) {
            override fun updateDrawState(ds: TextPaint) {
                super.updateDrawState(ds)
                ds.isUnderlineText = false
            }
        }, spannable.getSpanStart(u), spannable.getSpanEnd(u), 0)
    }
    text = spannable
}

उपयोग:

txtView.removeLinksUnderline()    

2

जब भी, मैं स्पैनबल के साथ URL को हटाने की कोशिश कर रहा हूँ, मैं केवल इन बातों का सुझाव देता हूँ:

1> कस्टम वर्ग बनाना:

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

इसके लिए URLSpan के एक अनुकूलित संस्करण की आवश्यकता होती है जो TextPaint की "अंडरलाइन" संपत्ति को सक्षम नहीं करता है

2> स्पैनबल पाठ के साथ सेटस्पैन:

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

इधर, spannableText की वस्तु है SpannableString ... !!!


यह सबसे अच्छा समाधान है और केवल यही मेरे लिए काम करता है
GuilhE

यह समाधान एक URL वाले पाठ के लिए है।
कूलमाइंड

1

यदि आप Textview ऑटोलिंक संपत्ति का उपयोग कर रहे हैं और आप रेखांकित करना चाहते हैं तो आप इसका उपयोग कर सकते हैं:

सबसे पहले, अंडरलाइनअप का विस्तार करें और अंडरलाइन को हटा दें:

public class NoUnderlineSpan extends UnderlineSpan {

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

दूसरा, NoUnderlineSpan का निर्माण और उदाहरण, स्ट्रिंग पाठ से एक Spannable बनाएँ और 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);
}

संदर्भ: http://prog3.com/sbdm/blog/maosidiaoxian/article/details/39156563


अच्छा समाधान है, लेकिन टेलीफोन ऐप से लौटने के बाद (फोन नंबर पर क्लिक करने के बाद) यह फिर से TextView को रेखांकित करता है।
कूलमैन्ड

1
हां, यदि आपकी गतिविधि पृष्ठभूमि पर जाती है, तो आपको टेक्स्ट कोड को रेखांकित नहीं करने के लिए अपने onResume गतिविधि फ़ंक्शन में इस कोड का उपयोग करना चाहिए।
फ्रांसिस्को मोया

0

यदि आप केवल पाठ चाहते हैं और URL लिंक के बारे में परेशान नहीं करते हैं

यह होगा पट्टी लिंक लेकिन रखने पाठ

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

कोई अतिरिक्त कक्षाएं आवश्यक नहीं हैं

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

0

यहाँ मेरा तरीका है

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

इसे इस तरह बुलाओ

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

Appcontroller मेरी एप्लिकेशन क्लास है जहां मैंने यह तरीका रखा है ताकि मैं इसे कहीं से भी एक्सेस कर सकूं


0

Xamarin उपयोगकर्ता इस पोस्ट को खोजने के लिए, यहां बताया गया है कि मुझे यह कैसे काम करना है:

  1. एक कस्टम स्पैन क्लास बनाएं, जो अंडरलाइनिंग को अलग करने के लिए संभालती है।
    class URLSpanNoUnderline : URLSpan {
            public URLSpanNoUnderline (string url) : base (url) {
            }

            public override void UpdateDrawState (TextPaint ds) {
                base.UpdateDrawState (ds);
                ds.UnderlineText = false;
            }
        }
  1. सभी url स्पैन खोजने के लिए और उन्हें हमारे कस्टम स्पैन से बदलने के लिए एक विस्तार विधि बनाएँ।
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 spans) {
                    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;
            }

-1
public void setView()
{
TextView t=(TextView) findViewById(R.id.textView3);
        t.setText(Html.fromHtml("<a href=http://www.urdusms.net > UrduSMS "));
        t.setTextColor(Color.BLACK);
        t.setGravity(Gravity.CENTER);
        t.setMovementMethod(LinkMovementMethod.getInstance());

         Spannable s = (Spannable) t.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 URLSpanline_none(span.getURL());
                s.setSpan(span, start, end, 0);
            }
        t.setText(s);
 }
//inner class is    
private class URLSpanline_none extends URLSpan {
            public URLSpanline_none(String url) {
                super(url);
            }
            @Override public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setUnderlineText(false);
            }
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.