31

I have textview which I need to linkify. Here's what I am doing..

TextView text = (TextView) view.findViewById(R.id.name);
text.setText("Android...Update from Android");
Pattern pattern = Pattern.compile("Android");
String scheme = "www.android.com";
Linkify.addLinks(text, pattern, scheme);

The text-view is displayed correctly with the text "Android...Update from Android", but I am facing two problems.

1) My text string has two instances of the string "Android". So, both the text are linkified. I want only the first occurrence to be linkified. How should I go about it?

2) When I click the linkfy text, it opens the browser, but the URL is weird. The url it tries to open is "www.comandroid". I don't know whats going wrong here. The text "android" in the URL is being replaced. Am I doing something wrong when Linknifying the text.

Any help will be highly appreciated.

Book Of Zeus
  • 49,509
  • 18
  • 174
  • 171
Faheem Kalsekar
  • 1,420
  • 3
  • 25
  • 31
  • 3
    Problem solved. Solution to the first problem is the answer provided by Ian Leslie. Solution to the second problem is as follows.The behavior of API "Linkify.addLinks" is such that, it appends the string that you want to linkify to the end of the url. For ex..if you want to linkify text "Android" with "www.android.com"..the final url is "www.android.comAndroid" which is not what I needed.So i used public static final void addLinks (TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter) – Faheem Kalsekar Jan 21 '11 at 04:44
  • TransformFilter transformFilter = new TransformFilter() {public final String transformUrl(final Matcher match, String url) { return ""; } }; The api transformFilter return a null string. So my final url is "www.android.com – Faheem Kalsekar Jan 21 '11 at 04:44

9 Answers9

26

The easy way is put autoLink in XML layout.

  android:autoLink="web" 
Fernando JS
  • 4,267
  • 3
  • 31
  • 29
24

I created a static method that does this simply:

/**
 * Add a link to the TextView which is given.
 * 
 * @param textView the field containing the text
 * @param patternToMatch a regex pattern to put a link around
 * @param link the link to add
 */
public static void addLink(TextView textView, String patternToMatch,
        final String link) {
    Linkify.TransformFilter filter = new Linkify.TransformFilter() {
        @Override public String transformUrl(Matcher match, String url) {
            return link;
        }
    };
    Linkify.addLinks(textView, Pattern.compile(patternToMatch), null, null,
            filter);
}

And the OP could use it simply:

addLink(text, "^Android", "http://www.android.com");
Shawn Lauzon
  • 6,234
  • 4
  • 35
  • 46
  • 4
    I spent quite a while trying to figure why this doesn’t work only to realize that when autolink is enabled this doesn’t work. When “auto-linking” is enabled, all additional Linkify operations are ignored. I ended up calling `text.setAutoLinkMask(0);` before calling this function and it did both autolink as well as this custom linkify. I hope this helps anyone else who faces the same issue. – Saifur Rahman Mohsin Jun 06 '17 at 07:16
9

I don't have much experience with Linkify. So far all I have wanted to do is make urls in the text into links which is handled automatically by a different version of addLinks.

However the regular expression you are using to match on "Android" can be changed to only match the one that starts the string by tweaking your regular expression:

Pattern pattern = Pattern.compile("^Android");

Notice the addition of '^'. This tells the regular expression matcher to only match the pattern 'Android' when it starts the string. If that will work with your strings then great. If you have other cases were the word you want to link is not at the beginning of the line you will need to explore regular expressions some more. I recommend this site to learn more regular-expressions.info

Ian Leslie
  • 841
  • 1
  • 9
  • 25
9

If you want to open all the urls which contains in text then you can do this..

            TextView textview=(TextView)findViewById(R.id.text);

    textview.setText("Android....Update from android...www.android.com");
    Linkify.addLinks(textview, Linkify.WEB_URLS);
    textview.setMovementMethod(LinkMovementMethod.getInstance());

It may work for all urls.

ankita gahoi
  • 1,532
  • 2
  • 15
  • 28
5

Here from Shawns answer and SpunkerBaba's comment I've come out with this helper class. This stops the issue of the double appending of what you are changing being added to your url.

package com.your.package;

public class Linkify {

    /**
     * @param textView
     *            textView who's text you want to change
     * @param linkThis
     *            a regex of what text to turn into a link
     * @param toThis
     *            the url you want to send them to
     */
    public static void addLinks(TextView textView, String linkThis, String toThis) {
        Pattern pattern = Pattern.compile(linkThis);
        String scheme = toThis;
        android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() {
            @Override
            public boolean acceptMatch(CharSequence s, int start, int end) {
                return true;
            }
        }, new TransformFilter() {

            @Override
            public String transformUrl(Matcher match, String url) {
                return "";
            }
        });
    }

}

Useage:

 Linkify.addLinks(profileTextView, "BlundellApps.com", "http://www.BlundellApps.com");
Blundell
  • 75,855
  • 30
  • 208
  • 233
3

I think what you really need is something as simple as:

final TextView textView = ((BodyViewHolder) holder).textView;
textView.setText(text);
Linkify.addLinks(textView, Linkify.WEB_URLS); // I would do this only during view creation, btw.

You're tracking an URL specifically. Some people suggest using Linkigy.ALL, but you don't want this:

public static final int ALL = WEB_URLS | EMAIL_ADDRESSES | PHONE_NUMBERS | MAP_ADDRESSES;

Also, other people are suggesting adding:

textview.setMovementMethod(LinkMovementMethod.getInstance());

after adding the link rules, but addLinks already does that in its insides ;-)

Cheers!

cesards
  • 15,882
  • 11
  • 70
  • 65
2

Problem solved. Solution to the first problem is the answer provided by Ian Leslie. Solution to the second problem is as follows.The behavior of API "Linkify.addLinks" is such that, it appends the string that you want to linkify to the end of the url. For ex..if you want to linkify text "Android" with "www.android.com". The final URL is "www.android.comAndroid" which is not what I needed.So i used

public static final void addLinks (TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter)
TransformFilter transformFilter = new TransformFilter() {
public final String transformUrl(final Matcher match, String url) { 
return ""; 
} }; 

The api transformFilter return a null string. So my final url is "www.android.com"

Jens Timmerman
  • 9,316
  • 1
  • 42
  • 48
Faheem Kalsekar
  • 1,420
  • 3
  • 25
  • 31
2
TextView noteView = (TextView) findViewById(R.id.noteview);
noteView.setText(someContent);
Linkify.addLinks(noteView, Linkify.ALL);
Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
Arpit Patel
  • 7,212
  • 5
  • 56
  • 67
1

For Koltin with lambda expression, it would be like this

val pattern = Pattern.compile(link.title)
Linkify.addLinks(view, pattern, null, null, { matcher, url -> link.href })
Kit
  • 2,370
  • 13
  • 11