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

3

7

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 :)

Anteversion answered 27/11, 2013 at 12:4 Comment(0)
A
11

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.

Anteversion answered 1/12, 2013 at 7:35 Comment(2)
Hi, Thanks for the solution i tried coping Linkify.java to my project but seems it is using some external libraries like libcore.util.EmptyArray and com.android.i18n which can not be imported to my project. Can you please post more information how you managed to work this. Thanks.Abeabeam
@Abeabeam - I had the same issue. I ended up creating a custom version of LinkifyCompat. That didn't require any extra libs.Tricorn
H
6

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.

Helgeson answered 14/1, 2016 at 8:50 Comment(0)
K
-9

Maybe you should use a WebView instead of a TextView?

Kalmuck answered 27/11, 2013 at 12:11 Comment(4)
I don't think using a webView for just displaying text with links is a solution. But thanks anyWay.Anteversion
But with a WebView you can handle your clicks yourself. BTW: Downvoting a workaround is rediculous. You won't get any further answers from anyone on Satckoverflow if you downvote workarounds instead of bad answers. Maybe you have to read again how downvoting works: stackoverflow.com/help/privileges/vote-downKalmuck
@Kalmuck Downvoting is only available once you are past 125 reputation, they only have 51.Gerek
@Kalmuck i didn't downvote your answer but i still think its a little overkill solution and im sure there is a way of just run over the Linkify's "OnClick". I'll use you answer as a final resort. And again, 10x :)Anteversion

© 2022 - 2024 — McMap. All rights reserved.