19

Hello I have set some text in a textview.

TextView tweet = (TextView) vi.findViewById(R.id.text);
tweet.setText(Html.fromHtml(sb.toString()));

Then I need to convert the text of the TextView into Spannble. So I did this like:

Spannable s = (Spannable) tweet.getText();

I need to convert it Spannable because I passed the TextView into a function:

    private void stripUnderlines(TextView textView) {
            Spannable s = (Spannable) 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);
        }

private class URLSpanNoUnderline extends URLSpan {
        public URLSpanNoUnderline(String url) {
            super(url);
        }

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

This shows no error/warning. But throwing a Runtime Error:

java.lang.ClassCastException: android.text.SpannedString cannot be cast to android.text.Spannable

How can I convert the SpannedStringt/text of the textview into Spannble? Or can I do the same task with SpannedString inside the function?

Kaidul
  • 15,409
  • 15
  • 81
  • 150

4 Answers4

24

How can I convert the SpannedStringt/text of the textview into Spannble?

new SpannableString(textView.getText()) should work.

Or can I do the same task with SpannedString inside the function?

Sorry, but removeSpan() and setSpan() are methods on the Spannable interface, and SpannedString does not implement Spannable.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • `new SpannableString(textView.getText())` I don't need this because `textView.getText()` is already `SpannedString`. I need to convert `textView.getText()` into `Spannable`. Is there any way? – Kaidul Jul 26 '13 at 13:23
  • 1
    @typedef: Please re-read my answer. Please note that I am having you construct a **`SpannableString`**. `SpannableString` implements `Spannable`. `SpannedString` does not. – CommonsWare Jul 26 '13 at 13:26
  • Sir, then how can I convert the underline of of the text of a textview. Can you give me some hints? – Kaidul Jul 26 '13 at 17:51
  • No problem, after applying it `new SpannableString(textView.getText())` its working! – Kaidul Jul 26 '13 at 17:57
  • 1
    @CommonsWare pls fix your article here - http://commonsware.com/blog/2013/10/23/linkify-autolink-need-custom-urlspan.html according to this your answer. – Stan Nov 07 '14 at 17:00
  • in my case when I am using new SpannableString(textView.getText()) the underline is not being removed. Hence I have written my code like this try { URLSpanNoUnderline.removeUnderlines((Spannable)txtAboutText.getText()); }catch (Exception e){ URLSpanNoUnderline.removeUnderlines(new SpannableString(txtAboutText.getText())); } – Anand Kumar Jha Sep 08 '16 at 07:18
2

This should be the correct work around. Its late tho but someone might need it in the future

private void stripUnderlines(TextView textView) {
        SpannableString 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);
    }



private class URLSpanNoUnderline extends URLSpan {
    public URLSpanNoUnderline(String url) {
        super(url);
    }

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

Unfortunately none of these worked for me but after fiddling around with all of your solutions I found something that worked.

It will error casting the textView.getText() to Spannable unless you specify it as SPANNABLE

Also Notice from @CommonsWare's page:

Note that you do not want to call setText() on the TextView, thinking that you would be replacing the text with the modified version. You are modifying the TextView’s text in place in this fixTextView() method, and therefore setText() is not necessary. Worse, if you are using android:autoLink, setText() would cause Android go back through and add URLSpans again.

accountAddressTextView.setText(accountAddress, TextView.BufferType.SPANNABLE);

stripUnderlines(accountAddressTextView);

private void stripUnderlines(TextView textView) {
    Spannable entrySpan = (Spannable)textView.getText();
    URLSpan[] spans = entrySpan.getSpans(0, entrySpan.length(), URLSpan.class);

    for (URLSpan span: spans) {
            int start = entrySpan.getSpanStart(span);
            int end = entrySpan.getSpanEnd(span);
            entrySpan.removeSpan(span);
            span = new URLSpanNoUnderline(entrySpan.subSequence(start, end).toString());
            entrySpan.setSpan(span, start, end, 0);
    }
}
ClayHerendeen
  • 187
  • 1
  • 4
  • 15
0

If you specify BufferType.SPANNABLE when setting the TextView's text, then when getting the text you can cast it to Spannable

myTextView.setText("hello", TextView.BufferType.SPANNABLE);
...
...
...
Spannable str = (Spannable) myTextView.getText();
marmor
  • 27,641
  • 11
  • 107
  • 150
  • Into the layout, the `textView` can also have `android:bufferType="spannable"` which is convenient – xiaomi Jun 12 '20 at 11:24