Open TextView links at another activity, not default browser

A-Live picture A-Live · Jul 10, 2012 · Viewed 7.6k times · Source

Having the textView with autoLinkMask set to Linkify.ALL, i'm able to open the links and the browser shows the web-page.

I need to call another activity that will do it with it's webView not leaving the application.

Important notes:

  • changing the textView content is not an option, i need to have the links displayed as they are with the schemes they have,
  • there's lot of text in the textView, not only the link.

I looked through movementMethod and IntentFilters, might miss something but looks like it can't help.

So, any option to intercept the touched link in the TextView to do something with it not opening the browser ?

If you want to mention this SO question, please give some arguments why cause it doesn't seem to solve the same problem as I have.

Answer

CommonsWare picture CommonsWare · Jul 10, 2012

Step #1: Create your own subclass of ClickableSpan that does what you want in its onClick() method (e.g., called YourCustomClickableSpan)

Step #2: Run a bulk conversion of all of the URLSpan objects to be YourCustomClickableSpan objects. I have a utility class for this:

public class RichTextUtils {
    public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(Spanned original,
    Class<A> sourceType,
    SpanConverter<A, B> converter) {
        SpannableString result=new SpannableString(original);
        A[] spans=result.getSpans(0, result.length(), sourceType);

        for (A span : spans) {
            int start=result.getSpanStart(span);
            int end=result.getSpanEnd(span);
            int flags=result.getSpanFlags(span);

            result.removeSpan(span);
            result.setSpan(converter.convert(span), start, end, flags);
        }

        return(result);
    }

    public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> {
        B convert(A span);
    }
}

You would use it like this:

yourTextView.setText(RichTextUtils.replaceAll((Spanned)yourTextView.getText(),
                                             URLSpan.class,
                                             new URLSpanConverter()));

with a custom URLSpanConverter like this:

class URLSpanConverter
      implements
      RichTextUtils.SpanConverter<URLSpan, YourCustomClickableSpan> {
    @Override
    public URLSpan convert(URLSpan span) {
      return(new YourCustomClickableSpan(span.getURL()));
    }
  }

to convert all URLSpan objects to YourCustomClickableSpan objects.