Custom clickable links in TextView

Gennady Kulabukhov
2 min readFeb 24, 2019

--

Often we need to display text with clickable links inside TextView. Something like this:

This can be easily done with android:linksClickable=”true” and android:autoLink=”all" attributes or Linkify.addLinks() method. Using these techniques we can handle different url schemas. For example, open https links in browser and tel schemas in phone dialer.

But this approach have some disadvantages. For example, by using above mentioned xml-attributes this link would not work:

<string name="text_with_link">By continuing you agree with service <a href="http://www.google.com">Terms of use</a></string>

To make it work, you should use following code instead of attributes:

textView.setMovementMethod(LinkMovementMethod.getInstance());

Now our link will be highlighted and clickable. But what if you want not only open links in browser, but run some custom logic? For example, log event to analytics or open another Activity on link click.

ClickableSpan

We can use ClickableSpan class to achieve our goal. This is an abstract class. So we need to subclass it and override onClick() method. After that we can attach instance of our ClickableSpan to SpannableString using setSpan() method for later use in TextView.

Something like this:

ClickableSpan clickableSpan = ... // create custom ClickableSpanSpannable spannableText = new SpannableString("Clickable text");
spannableText.setSpan(clickableSpan, 0, spannableText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableText);

To make this code more handy, lets create ClickSpan class that inherits from ClickableSpan

This class should help us to add clickable links to TextView with custom handlers in an easy manner. I’ve ended up with following Java implementation:

As we can see, our class defines OnClickListener interface with single onClick() method which will be used to handle clicks. Also our class contains two static clickify() methods, that we can used to easily attach links to TextView. All you need to do, is to pass TexView with String you want to wrap with link and instance of OnClickListener

By default, links are drawn underlined. Sometimes this is not desired behaviour. If we want to draw our links without underline, we can use second clickify() method, which receives boolean parameter withUnderline and pass false value.

Now we can use our ClickSpan class. Firstly lets define texts inside strings.xml:

After that we can add links to TextView with following code (written in Kotlin):

Now we can define any logic inside our handlers.

Conclusion

Links handling inside TextView can be done by using different approaches. You can use framework-provided classes and xml-attributes. For many cases they work just fine.

But if you want to implement custom links handling, it may be required to write some code. I have used above mentioned ClickSpan class in many projects and it just works. It is small and can be easily changed to your needs.

--

--