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

Shirane85
  • 2,255
  • 1
  • 26
  • 38

3 Answers3

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.

Shirane85
  • 2,255
  • 1
  • 26
  • 38
  • 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. – user465125 Nov 08 '17 at 07:36
  • @user465125 - I had the same issue. I ended up creating a custom version of LinkifyCompat. That didn't require any extra libs. – Phill Wiggins Aug 16 '21 at 09:04
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.

PH88
  • 1,796
  • 12
  • 12
-9

Maybe you should use a WebView instead of a TextView?

kirsche40
  • 981
  • 1
  • 10
  • 19
  • I don't think using a webView for just displaying text with links is a solution. But thanks anyWay. – Shirane85 Nov 27 '13 at 13:37
  • 1
    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: http://stackoverflow.com/help/privileges/vote-down – kirsche40 Nov 27 '13 at 20:42
  • @kirsche40 Downvoting is only available once you are past 125 reputation, they only have 51. – hichris123 Nov 27 '13 at 21:26
  • @kirsche40 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 :) – Shirane85 Nov 28 '13 at 07:18