Handle clicks on TextView's links while using Linkify for finding and setting the links inside the text

6.9k views Asked by At

i have a TextView filled with text which i get from a server. I'm using Linkify for handling all the link searching and for setting a URLSpan where needed throughout its addLinks method.

The problem is that the default behavior when clicking a link is opening it in a browser, what i want is to get the clicked link and handle it my self.

I don't see any method of Linkify which let me set a "OnClick" or something...

Thank for your help :)

3

There are 3 answers

2
Shirane85 On BEST ANSWER

Ok so i finally managed to set my own "OnClickListener" to the TextView's links. My solution was to copy Linkify to my project, name it CustomLinkify and just change its applyLink method:

From:

private static final void applyLink(String url, int start, int end, Spannable text) 
{
    URLSpan span = new URLSpan(url);

    text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

To:

private static final void applyLink(final String url, int start, int end, Spannable text) 
{
    URLSpan span = new URLSpan(url)
    {
        @Override
        public void onClick(View widget)
        {
            _onLinkClickListener.onLinkClicked(url);
        }
    };

    text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

Where _onLinkClickListener is a new field, set by me before using the new CustomLinkify.

I know its not a very elegant solution and i prefered google to allow setting a listener through the native Linkify, but, for me, this is better than implementing my own Spannable logics (as suggested in other related questions).

I trust the Linkify code and i guess i'll check from time to time to see if any changes made on it, if so, i'll of course update CustomLinkify with the changes.

Hope this will help someone.

4
kirsche40 On

Maybe you should use a WebView instead of a TextView?

0
PH88 On

I also find it tedious to implement custom Spannable logics in app, and end up creating a library for this. See Textoo.

With Textoo, this can be achieve like:

TextView myTextView = Textoo
    .config((TextView) findViewById(R.id.my_text_view))
    .linkifyEmailAddresses()
    .linkifyMapAddresses()
    .linkifyPhoneNumbers()
    .linkifyWebUrls()  // or just .linkifyAll()
    .linkify(patternSettings, "internal://settings/")
    .linkify(patternGoogle, "http://www.google.ie/search2?q=", null, transformFilter)
    .linkify(patternGoogle, "http://www.google.ie/search3?q=", matchFilter, transformFilter)
    .addLinksHandler(new LinksHandler() {
        @Override
        public boolean onClick(View view, String url) {
            if ("internal://settings/location".equals(url)) {
                Intent locSettings = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(locSettings);
                return true;
            } else {
                return false;
            }
        }
    })
    .apply();

Just to share and hope somebody will find it useful.