A better way to handle links in TextView

There are two ways of “linkifying” URLs in a TextView. First, as an XML attribute:

and second, programmatically:

In both the cases, the framework internally registers a LinkMovementMethod on the TextView that handles dispatching a “ACTION_VIEW" Intent when any link is clicked. This is why phone-numbers open in a dialer when clicked, web URLs open in a browser, map URLs open in Google Maps and so on.

The source can be seen in URLSpan.class (line #63):

The problem with the default LinkMovementMethod is that it’s buggy and non-customizable:

1. Incorrect touch areas

It incorrectly calculates a URL’s bounds when the URL is present at any horizontal/vertical end and there’s space available in that direction inside the TextView (including its padding). This is like having ghost links in our app and that’s not good.

2. Unreliable highlighting

LinkMovementMethod highlights a URL only the first time it’s clicked and it stops working randomly after that. It also does not correctly track the touch pointer to unhighlight the URL once it’s no longer being touched.

3. No support for custom URL handling

We’re also out of luck if we want to show contextual options when a phone-number is clicked instead of simply redirecting to the dialer.

BetterLinkMovementMethod

Introducing BetterLinkMovementMethod, a.. uh.. better a version of LinkMovementMethod that solves all our problems. It’s designed to be a drop-in replacement for LinkMovementMethod:

However, the easiest way to get started is by using one of its linkify() methods:

Update: v1.1 introduces a new method for fixing its compatibility with links inserted using Html.fromHtml():

Download

Add this to your module’s build.gradle:

Examples

Registering a BetterLinkMovementMethod on a TextView:

or on infinite TextViews:

Adding a click listener:

You can also choose to go the shorter route of registering BetterLinkMovementMethod on all TextViews in your Activity’s layout in one go:

When using in a non-Activity context (e.g., Fragments), you can also pass a ViewGroup as the 2nd param:

Source

BetterLinkMovementMethod is available on Github. Feel free to raise issues, send contributions or fork it for your own usage.

https://github.com/Saketme/Better-Link-Movement-Method

View All