89

I have a Spannable Object with a Clickable Object set to it. When the Spannable String is displayed in the TextView it has blue text and a blue underline (indicating to the user that this Text is Clickable). My problem is how can I prevent appearing the blue underline in TextView?

Masa
  • 290
  • 4
  • 17
Ash
  • 1,241
  • 1
  • 9
  • 16

10 Answers10

155

Use the below code and try

String mystring =" Hello";
SpannableString ss= new SpannableString(mystring);
ss.setSpan(new MyClickableSpan(mystring), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  

class MyClickableSpan extends ClickableSpan{// extend ClickableSpan     

    String clicked;
    public MyClickableSpan(String string) {
        super();
        clicked = string;
    }
    @Override
    public void onClick(View tv) {
       Toast.makeText(MainActivity.this,clicked , Toast.LENGTH_SHORT).show();
    }

    @Override
    public void updateDrawState(TextPaint ds) {// override updateDrawState
        ds.setUnderlineText(false); // set to false to remove underline
    }
}
lasseg
  • 11
  • 5
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • 10
    `ds.setColor(Color.rgb(0, 0 , 255));` to keep a blue color on the spannable string (or change it to any color you want). – Hugo Allexis Cardona Mar 06 '18 at 17:42
  • We can set other properties in updateDrawState(TextPain ds){} method – Parth Patel Aug 08 '19 at 14:25
  • Weird that there's no better solution for this (posted here at least). updateDrawState is called a lot of times and this isn't the right place to configure the paint. – User Jan 17 '20 at 10:51
71

This works for me. No need to create custom ClickableSpan class. Just override updateDrawState(TextPaint ds).

SpannableString span = new SpannableString("Some text");
ClickableSpan clickSpan = new ClickableSpan() {
    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setColor(ds.linkColor);    // you can use custom color
        ds.setUnderlineText(false);    // this remove the underline
    }

    @Override
    public void onClick(View textView) {
        // handle click event
    }
};

span.setSpan(clickSpan, 5, span.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourTextView.setText(span);
ARiF
  • 1,079
  • 10
  • 23
8

Raghunandan's answer works perfectly for me. Here is a pared-down version of it:

public abstract class NoUnderlineClickableSpan extends ClickableSpan {    
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
    }
}
Jo Jo
  • 7,245
  • 5
  • 34
  • 49
6

Override updateDrawState method of ClickableSpan class

String mystring =" Hello";
SpannableString ss= new SpannableString(mystring);
ss.setSpan(new MyClickableSpan(mystring), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  

class MyClickableSpan extends ClickableSpan{// extend ClickableSpan     

String clicked;
public MyClickableSpan(String string) {
    // TODO Auto-generated constructor stub
super();
clicked =string;
}

public void onClick(View tv) {

   Toast.makeText(MainActivity.this,clicked ,
        Toast.LENGTH_SHORT).show();
}

public void updateDrawState(TextPaint ds) {// override updateDrawState
   ds.setUnderlineText(false); // set to false to remove underline
}

For changing color of spannable String

  SpannableString    ss = new SpannableString("android Stack Overflow");

  ForegroundColorSpan fcs=newForegroundColorSpan(Color.parseColor("#01579B"));
  ss.setSpan(fcs, 8,13, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Sanjay Jain
  • 651
  • 1
  • 8
  • 10
4

spannableStringObject.toString();

Edit

SpannableString ss = getYourSpannableString();
UnderlineSpan[] uspans = ss.getSpans(0, ss.length(), UnderlineSpan.class);
for (UnderlineSpan us : uspans) {
    ss.removeSpan(us);
}

Will remove all the UnderlineSpans from the Spannable.

dcow
  • 7,765
  • 3
  • 45
  • 65
  • Just tried the above answer, it does work but my Clickable Object does not work now? – Ash Apr 15 '13 at 03:31
  • @Ash I have no idea what that means.. why don't you provide a little more background and context in your question. – dcow Apr 15 '13 at 03:32
  • toString returns the characters represented by the SpannableString since SpannableString implements CharacterSequence. What I have show above will remove all formatting from the SpannableString. – dcow Apr 15 '13 at 03:33
  • Just added a little more background to my question. – Ash Apr 15 '13 at 03:41
  • toString() literally gets rid of the Clickable object which I need. – Ash Apr 15 '13 at 03:45
  • @Ash because your question is entirely bad. Have you used this site before? – dcow Apr 15 '13 at 04:48
  • @Ash the edit made it better.. but still it's not clear what the problem is and how you would like it resolved. I'm assuming from the question you have a SpannableString and you want to remove the underline from the links or something. But, I really don't have any idea because you haven't explained any of it. – dcow Apr 15 '13 at 04:50
  • Yes I have used this site before. I did some research on this problem I have and could not find anything. So I thought maybe posting it on stackoverflow might help but it looks like people don't understand the context of my question although I have edited it like three times. If I had more reputation I would have uploaded some pictures to go with it but I don't. My bad for not writing a good question, do you have any tips that could help me in writing better questions for the future? – Ash Apr 15 '13 at 04:56
  • I never gave you a down vote.. I'm just answering your second question which was why all the down votes. To improve your question I suggest adding sample code and a dialog about what you have tried so far as well as some details explaining what you want the end goal to be. It may be that your problem can be solved in a method other than the one you are currently attempting.. – dcow Apr 15 '13 at 05:07
  • You question is fine now (after the edit like 12 seconds ago) -- although there is still always room for more details and examples of what doesn't work. Consequently, my answer does not solve your problem (now that you've clarified what it is). I'll look into it when I can (= – dcow Apr 15 '13 at 05:08
  • Sorry, I thought you were one of the guys that down voted. My bad, Thanks for the tips though, I will be using them in future posts that I make. – Ash Apr 15 '13 at 07:17
  • No it does not work, might it be because I am using it on a SpannableStringBuilder object? It should work on either SpannableString or SpannableStringBuilder but it does not? – Ash Apr 15 '13 at 08:08
  • I just tried Raghunandans answer and that works fine, Thanks for all your help. – Ash Apr 15 '13 at 08:18
3

simplest way is

 string1 = new SpannableString("By Tapping Register You Agree To The \nTerms And Conditions");
    ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(getApplicationContext(),"clicked",Toast.LENGTH_SHORT).show();
        }
        @Override
        public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);    // this line removes underline
        }

    };
    text_terms.setMovementMethod(LinkMovementMethod.getInstance());
    string1.setSpan(clickableSpan,37,string1.length(),0);
    text_terms.setText(string1);
saigopi.me
  • 14,011
  • 2
  • 83
  • 54
3

Based on the answer of @Sai Gopi Me

in Kotlin:

val clickableSpan: ClickableSpan = object : ClickableSpan() {
    override fun onClick(widget: View) {
        // some action here
    }
                
    override fun updateDrawState(ds: TextPaint) {
        super.updateDrawState(ds)
        ds.isUnderlineText = false
        }
    }
}
Azhagthott
  • 492
  • 5
  • 13
1
Try the below code to remove underlined and clicked event on multiple words in textview :



            String str="Angelina Clapped For Lester Kang";
            Spannable span = Spannable.Factory.getInstance().newSpannable(str);

            // 0 to 8 start and  index of Angelina
            span.setSpan(new ClickableSpan(str), 0, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

             //  21 to 32  start and  index of Lester  Kang
            span.setSpan(new ClickableSpan(str), 21, 32, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            textview.setText(span);

             class ClickableSpan extends ClickableSpan{

                    String clicked;
                    public ClickableSpan (String string) {
                        super();

                    }

                    public void onClick(View v) {
                        Toast.makeText(MyActivity.this,""+((TextView)v).getText().toString(),Toast.LENGTH_SHORT).show();
                    }

                    public void updateDrawState(TextPaint ds) {
                       // override updateDrawState
                        ds.setUnderlineText(false); // set to false to remove underline
                    }
                }
Pradeep Gupta
  • 1,770
  • 1
  • 9
  • 23
1

ANURAG RASTOGI's answer saved the day for me! I already have a formatted SpannableString on which I wanted to apply a ClickableSpan:

spannableString.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        // Do something...
    }
    // Prevent
    // ds.setColor(ds.linkColor);
    // ds.setUnderlineText(true);
    // in: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/style/ClickableSpan.java
    // from executing.
    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
        // super.updateDrawState(ds);
    }
},0, spannableString.length(), SPAN_EXCLUSIVE_EXCLUSIVE);

The updateDrawState overrides the updateDrawState in the ClickableSpan class in Android, and by not calling super.updateDrawState it will not get executed.

All text formatting already present in spannableString will be preserved.

0

If you do not want any pre-applied attributes do not call super.updateDrawState(). On overriding updateDrawState(object:Textpaint) with help of object you can apply or call different functions present in Text Paint.