1150

I have the following TextView defined:

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:text="@string/txtCredits"
    android:autoLink="web" android:id="@+id/infoTxtCredits"
    android:layout_centerInParent="true"
    android:linksClickable="true"/>

where @string/txtCredits is a string resource that contains <a href="some site">Link text</a>.

Android is highlighting the links in the TextView, but they do not respond to clicks. What am I doing wrong? Do I have to set an onClickListener for the TextView in my activity for something as simple as this?

It looks like it has to do with the way I define my string resource.

This does not work:

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>

But this does:

<string name="txtCredits">www.google.com</string>

Which is a bummer because I would much rather show a text link than show the full URL.

Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Richard
  • 28,691
  • 8
  • 33
  • 34

40 Answers40

1346

Buried in the API demos, I found the solution to my problem:

File Link.java:

    // text2 has links specified by putting <a> tags in the string
    // resource.  By default these links will appear but not
    // respond to user input.  To make them active, you need to
    // call setMovementMethod() on the TextView object.

    TextView t2 = (TextView) findViewById(R.id.text2);
    t2.setMovementMethod(LinkMovementMethod.getInstance());

I removed most of the attributes on my TextView to match what was in the demo.

<TextView
    android:id="@+id/text2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/txtCredits"/>

That solved it. It is pretty difficult to uncover and fix.

Important: Don't forget to remove autoLink="web" if you are calling setMovementMethod().

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Richard
  • 28,691
  • 8
  • 33
  • 34
  • Unfortunately, this solution has a side effect when used with EditText. It disables action bar onLongClick and positions a cursor at the beginning of EditText. – bancer Apr 27 '12 at 20:01
  • 23
    Maybe it's just me, but why would you ever do this with an EditText? – Justin May 08 '12 at 18:41
  • 1
    Turns out only setMovementMethod is needed to achieve the goal. – superarts.org Aug 30 '12 at 03:39
  • 1
    Thanks for this, been pulling my hair out all day on what should have been a simple task! In case anyone needs to implement this on the Master-detail fragment template provided by the SDK these days, I did it like this in the onCreateView method of the DetailFragment Activity: if (mItem != null) { ((TextView) rootView.findViewById(R.id.factsheet_detail)).setText(mItem.description); ((TextView) rootView.findViewById(R.id.factsheet_detail)).setMovementMethod(LinkMovementMethod.getInstance()); } – BasicPleasureModel Sep 11 '12 at 15:07
  • This worked great for me as well, thank you so much!! I do have one question - the whitespace area to the right of my links, after the closing `` tag, is also clickable and therefore making it difficult to scroll through my list of results. Any thoughts? – Valdogg21 May 11 '13 at 20:39
  • 1
    This is the best way... and don't forget you can create a new LinkMovementMethod like so: setMovementMethod(new LinkMovementMethod() { @Override public boolean onTouchEvent( – Codeversed Dec 05 '13 at 17:18
  • 3
    Just as a commment, i have seen some Samsung Galaxy S3 with OS 4.3 that crash when the "setMovementMethod(LinkMovementMethod.getInstance())" is used, so just take that into account, i had to create a validation before adding it – Jorge Aguilar Mar 25 '14 at 18:24
  • 45
    Same here. Note that if setMovementMethod() is called, it is necessary to remove autolink="web" in the XML file, or else link won't work. Thanks for the comment – voghDev May 05 '14 at 10:04
  • 1
    android:linksClickable="true" in textview is by default clickable.No need of mentioning out in textview tag. – Ajay Takur Oct 20 '14 at 23:05
  • also make sure you don't have android:autoLink="web", as setting this along with using LinkMovementMethod won't work. – jiawen Apr 17 '15 at 02:35
  • 7
    Just use the "autoLink" attribute in your xml for eg: android:autoLink = "web" – Kalpesh May 22 '15 at 05:48
  • Maybe using autoLink="web" in your textview should do the trick, have you tried it ? – Jav T May 04 '16 at 17:24
  • Using this code the link is clickable but after clicking it i get a dialog/Fragment with title "Open with" and in description it states "No apps can perform this action." – Darshan Miskin Nov 02 '16 at 06:01
  • Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? – Iman Marashi Apr 22 '17 at 16:57
  • Have found this to be the simplest, and most reliable solution. autolink does not work, even when testing with and without "linksClickable=true". It formats the URL but it does not launch the link. Google, why is this a mess. +1 – angryITguy May 08 '18 at 00:44
  • if URL starts with a capital letter then it's not working ex: Https://syakt.wordpress.com or HTTPS://ME.COM – Surendar Dharavath Jun 27 '18 at 11:59
  • "autoLink" attribute does not work on all the devices means, If you have not inserted sim card in the phone then it does not work. I tried all the workarounds but finally I found this case. Otherwise we can display phone number with country code prefixed. I have just shared my findings. – Tejas Shelke Mar 23 '20 at 07:16
  • But how do I add style to the a tag? I tried but it doesn't work... – Rondev Sep 22 '20 at 09:31
589

I'm using only android:autoLink="web" and it works fine. A click on the link opens the browser and shows the correct page.

One thing I could guess is that some other view is above the link. Something that is transparent fills the whole parent but don't displays anything above the link. In this case the click goes to this view instead of the link.

Janusz
  • 187,060
  • 113
  • 301
  • 369
  • 3
    Added more info above. Could it be the way I am defining the string as Google? Looks like this is allowed but it's not working for me. – Richard Apr 29 '10 at 22:46
  • 6
    if you use linkify auto you don't need the a href part. The OS will take the string parse it for urls and converts every url to a clickable link. But this won't result in the word google being linked to google.com. It would display www.google.com as link. – Janusz Apr 30 '10 at 06:37
  • using autolink works perfect for me too, plain textview without parent at all. – euther Dec 05 '11 at 00:52
  • 2
    android:autoLink also works great for linkifying phone numbers, addresses, and e-mail addresses (or all of the above). – Cloudy Mar 23 '12 at 20:38
  • 62
    No it's not, because this answer doesn't work if you wan't to use an anchor tag with a display text different from the URL – cprcrack Jan 25 '14 at 18:38
  • This is very helpful. I need it for calling so i use the `android:autoLink="phone"` and it works :) – Lee Yi Hong Jan 05 '15 at 11:42
  • 2
    Yeah, it works!. You can change the link color using this attribute in xml. `android:textColorLink="#03A9F4"` – Disapamok Jul 24 '16 at 16:33
  • I prefer `android:autoLink="all"` for every kind of link and add `android:linksClickable="true"` to be more "secure". – Beeing Jk Mar 27 '17 at 03:55
460

After spending some time with this, I have found that:

  • android:autoLink="web" works if you have full links in your HTML. The following will be highlighted in blue and clickable:
  • Some text <a href="http://www.google.com">http://www.google.com</a>
  • Some text http://www.google.com
  • view.setMovementMethod(LinkMovementMethod.getInstance()); will work with the following (will be highlighted and clickable):
  • Some text <a href="http://www.google.com">http://www.google.com</a>
  • Some text http://www.google.com
  • Some text <a href="http://www.google.com">Go to Google</a>

Note that the third option has a hyperlink, but the description of the link (the part between the tags) itself is not a link. android:autoLink="web" does NOT work with such links.

  • android:autoLink="web" if set in XML will override view.setMovementMethod(LinkMovementMethod.getInstance()); (i.e.; links of the third kind will be highlighted, but not clickable).

The moral of the story is use view.setMovementMethod(LinkMovementMethod.getInstance()); in your code and make sure you don't have android:autoLink="web" in your XML layout if you want all links to be clickable.

Jeshurun
  • 22,940
  • 6
  • 79
  • 92
  • 1
    setMovementMethod doesn't work with second option you mentioned ie http://www.google.com.. any update? – Darpan Mar 13 '15 at 10:33
  • 34
    Thanks for pointing out that `Go to Google` won't work for autoLink. For so many answers on SO, this is the only one which mentioned it. Thank you! – cwhsu Dec 29 '16 at 09:23
  • setMovementMethod doesn't work for plain text urls... like https://www.google.com/ – RAINA Nov 10 '22 at 17:27
108

The above solutions didn't work for me, but the following did (and it seems a bit cleaner).
First, in the string resource, define your tag opening chevrons using the HTML entity encoding, i.e.:

&lt;a href="http://www.google.com">Google&lt;/a>

And not:

<a href="http://www.google.com">Google</a>

In general, encode all the chevrons in the string like that. BTW, the link must start with http://

Then (as suggested here) set this option on your TextView:

 android:linksClickable="true"

Finally, in code, do:

((TextView) findViewById(R.id.your_text_view)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.your_text_view)).setText(Html.fromHtml(getResources().getString(R.string.string_with_links)));

That's it. No regular expressiones or other manual hacks are required.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Błażej Czapp
  • 2,478
  • 2
  • 24
  • 18
90

I simply used this:

Linkify.addLinks(TextView, Linkify.ALL);

It makes the links clickable, given here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jai_b
  • 1,113
  • 7
  • 7
74

If you want to add an HTML-like link, all you need to do is:

  • add a resource HTML-like string:

      <string name="link"><a href="https://www.google.pl/">Google</a></string>
    
  • add your view to the layout with no link-specific configuration at all:

      <TextView
         android:id="@+id/link"
         android:text="@string/link" />`
    
  • add the appropriate MovementMethod programmatically to your TextView:

      mLink = (TextView) findViewById(R.id.link);
      if (mLink != null) {
        mLink.setMovementMethod(LinkMovementMethod.getInstance());
      }
    

That's it! And yes, having options like "autoLink" and "linksClickable" working on explicit links only (not wrapped into HTML tags) is very misleading to me too...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vizZ
  • 1,530
  • 14
  • 14
  • 2
    +1 You're right. There should be an option to enter a pattern your self so that this is matched. This way it's pretty dumb. – schlingel Aug 21 '12 at 09:43
68

The following should work for anyone who is looking for a combination of text and hyperlink within an Android app.

In string.xml:

<string name="applink">Looking for Digital Visiting card? 
<a href="https://play.google.com/store/apps/details?id=com.themarkwebs.govcard">Get it here</a>
</string>

Now you can utilise this string in any given View like this:

<TextView
    android:id="@+id/getapp"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:gravity="center"
    android:textColor="@color/main_color_grey_600"
    android:textSize="15sp"
    android:text="@string/applink"/>

Now, in your Activity or Fragment, do the following:

TextView getapp =(TextView) findViewById(R.id.getapp);
getapp.setMovementMethod(LinkMovementMethod.getInstance());

By now, you don't require to set android:autoLink="web" or android:linksClickable="true" using this approach.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Asesha George
  • 2,232
  • 2
  • 32
  • 68
54

I added this line to the TextView: android:autoLink="web"

Below is an example of usage in a layout file.

layout.xml

<TextView
    android:id="@+id/txtLostpassword"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:autoLink="email"
    android:gravity="center"
    android:padding="20px"
    android:text="@string/lostpassword"
    android:textAppearance="?android:attr/textAppearanceSmall" />

<TextView
    android:id="@+id/txtDefaultpassword"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:autoLink="web"
    android:gravity="center"
    android:padding="20px"
    android:text="@string/defaultpassword"
    android:textAppearance="?android:attr/textAppearanceSmall" />

string.xml

<string name="lostpassword">If you lost your password please contact <a href="mailto:support@cleverfinger.com.au?Subject=Lost%20Password" target="_top">support@cleverfinger.com.au</a></string>

<string name="defaultpassword">User Guide <a href="http://www.cleverfinger.com.au/user-guide/">http://www.cleverfinger.com.au/user-guide/</a></string>
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Shanewaj
  • 2,078
  • 1
  • 20
  • 16
37

I hope this will help you;

String value = "<html>Visit my blog <a href=\"http://www.maxartists.com\">mysite</a> View <a href=\"sherif-activity://myactivity?author=sherif&nick=king\">myactivity</a> callback</html>";
TextView text = (TextView) findViewById(R.id.text);

text.setText(Html.fromHtml(value));
text.setMovementMethod(LinkMovementMethod.getInstance());
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bebin T.N
  • 2,539
  • 1
  • 24
  • 28
  • 3
    This works great. Also make sure you remove `android:autoLink=?` from your `TextView`. – sulai Oct 17 '13 at 13:44
  • This is what finally worked for me. Valid HTML and not using `android:autoLink=?` is important! – Neal Sanche Oct 23 '13 at 22:55
  • For Xamarin, the word shows but is not underlined and can't be clicked using the above and NOT these parameters: autoLink, linksClickable – maxweber Nov 01 '13 at 15:35
  • For Xamarin setting those and setting Text or setting TextFormatted also yields the word but its not clickable nor blue/underlined. Removing the autoLink also fails. Removing only linksClickable also fails. Removing both also fails. – maxweber Nov 01 '13 at 15:37
  • helloWorld.TextFormatted = Html.FromHtml (linkURL); with and without those also fails. (not linked, not blue, can't be clicked) – maxweber Nov 01 '13 at 15:49
  • Those are failed using the "normal" html as listed above in this proposed solution. Escaping the HTML with > etc leads to garbage (markup shown) when using TextFormatted and when using text when liunksCLickable is set but autoLink is not. – maxweber Nov 01 '13 at 15:52
  • using autoLink="web" without linksClickable and with HTML escaped did not work also. With HTML not escaped, it is garbage but at least the link can be clicked. Duh, back where started. – maxweber Nov 01 '13 at 15:57
  • Xamarin issue: tv.Text can only be set to string and toString on Html.FromHTML (an ISpanned) is a string of only the label and not the link info. Similarly, tv.SetText is not valid as it is in Java. Seems to be some issue in the Xamarin mapping? – maxweber Nov 01 '13 at 16:09
  • Here is a Xamarin example. Does not work for me: http://stackoverflow.com/questions/18555862/how-to-hyperlink-textview-in-c-sharp-android – maxweber Nov 01 '13 at 16:23
  • adding the tag is the key difference for this solution. – Droid Teahouse Feb 27 '18 at 20:20
  • Try adding style to the a element, it doesn't work, can't change it's color or remove underline – Rondev Sep 22 '20 at 09:19
30

The easiest thing that worked for me was to use Linkify

TextView txt_Message = (TextView) view.findViewById(R.id.txt_message);
txt_Message.setText("This is link https://www.google.co.in/");
Linkify.addLinks(txt_Message, Linkify.WEB_URLS);

And it will automatically detect the web URLs from the text in the textview.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pravesh
  • 822
  • 1
  • 8
  • 20
26

You only need to add this in the text view in XML:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:autoLink="web"/>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ahmed Mostafa
  • 379
  • 3
  • 4
25

Manage Linkify text color also

Enter image description here

tv_customer_care_no.setLinkTextColor(getResources().getColor(R.color.blue));
tv_customer_care_no.setText("For us to reach out to you, please fill the details below or contact our customer care at 18004190899 or visit our website http://www.dupont.co.in/corporate-links/contact-dupont.html");
Linkify.addLinks(tv_customer_care_no, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
Linkify.addLinks(tv_customer_care_no, Linkify.ALL);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
23

By using linkify:

Linkify takes a piece of text and a regular expression and turns all of the regex matches in the text into clickable links:

TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("http://example.com");
Linkify.addLinks(textView, Linkify.WEB_URLS);

Don't forget to

import android.widget.TextView;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DeathRs
  • 1,100
  • 17
  • 22
23

Here is a very one-line Android code to make phone and URL selectable from textView no matter what the string is and what the data is. You don’t need to use any HTML tags for this.

TextView textView = (TextView)findViewById(R.id.textView1);
textView.setText("some URL is www.google.com phone 7504567890 another URL lkgndflg.com ");

// Makes the textView's Phone and URL (hyperlink) select and go.
Linkify.addLinks(textView, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rahul Raina
  • 3,322
  • 25
  • 30
22

Richard, next time, you should add this code under TextView at the layout XML instead.

android:autoLink="all"

This should be like this.

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:text="@string/txtCredits"
    android:id="@+id/infoTxtCredits"
    android:autoLink="all"
    android:linksClickable="true">
</TextView>

You don't need to use this code (t2.setMovementMethod(LinkMovementMethod.getInstance());) in order to make the link clickable.

Also, here's the truth: as long as you set the autoLink and the linksClickable, don't forget to add this at String.xml file so that the clickable link will work.

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>
Reed
  • 14,703
  • 8
  • 66
  • 110
David Dimalanta
  • 548
  • 6
  • 19
15

I noticed that using android:autoLink="web" thus

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:autoLink="web"/>

worked OK for URLs but since I had an e-mail address and phone number that I wanted to link as well, I ended up using this line android:autoLink="all" like this

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:autoLink="all"/>

and it worked like a charm.

aLearner
  • 1,051
  • 14
  • 30
15

The accepted answer is correct, but it will mean that phone numbers, maps, email addresses, and regular links, e.g., http://google.com without href tags will no longer be clickable since you can't have an autolink in the XML content.

The only complete solution to have everything clickable that I have found is the following:

Spanned text = Html.fromHtml(myString);
URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);
SpannableString buffer = new SpannableString(text);
Linkify.addLinks(buffer, Linkify.ALL);
for (URLSpan span : currentSpans) {
    int end = text.getSpanEnd(span);
    int start = text.getSpanStart(span);
    buffer.setSpan(span, start, end, 0);
}
textView.setText(buffer);
textView.setMovementMethod(LinkMovementMethod.getInstance());

And the TextView should not have android:autolink. There's no need for android:linksClickable="true" either; it's true by default.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kelly McKinnon
  • 186
  • 1
  • 3
13

Add this to your EditText:

android:autoLink="web"
android:linksClickable="true"
Ramesh R
  • 7,009
  • 4
  • 25
  • 38
Ajaz Ahmed
  • 315
  • 4
  • 18
12

You need only this:

android:autoLink="web"

Insert this line into a TextView that can be clickable with a reference to the web. The URL is set as a text of this TextView.

Example:

 <TextView
    android:id="@+id/textViewWikiURL"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:textStyle="bold"
    android:text="http://www.wikipedia.org/"
    android:autoLink="web" />
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Androdos
  • 653
  • 8
  • 11
12

Be sure to not use setAutoLinkMask(Linkify.ALL) when using setMovementMethod(LinkMovementMethod.getInstance()) and Html.fromHTML() on properly formatted HTML links (for example, <a href="http://www.google.com/">Google</a>).

Piyush
  • 18,895
  • 5
  • 32
  • 63
elevenfive
  • 168
  • 1
  • 4
11

Use this...

TextView.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Intent in=new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.twitter.com/"));
                        startActivity(in);
                    }
                    
                });

And add a permission in the manifest file:

<uses-permission android:name="android.permission.INTERNET"/>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tej
  • 399
  • 1
  • 5
  • 21
9

Use the below code:

String html = "<a href=\"http://yourdomain.com\">Your Domain Name</a>"
TextView textview = (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(html));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Phuc Tran
  • 7,555
  • 1
  • 39
  • 27
9

This is how I solved clickable and visible links in a TextView (by code)

private void setAsLink(TextView view, String url){
    Pattern pattern = Pattern.compile(url);
    Linkify.addLinks(view, pattern, "http://");
    view.setText(Html.fromHtml("<a href='http://" + url + "'>http://" + url + "</a>"));
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dominic
  • 3,353
  • 36
  • 47
  • but I'd like to see the text and when clicking the text it redirect to the link (opened by the browser)? This solution doesn't solve that, does it? – Duc Tran Dec 12 '12 at 13:06
8

[Tested in Pre-lollipop as well as in Lollipop and above]

You can get your HTML string from the backend or from your resources files. If you put your text as an resource string, make sure to add the CDATA tag:

<string name="your_text">![CDATA[...<a href="your_link">Link Title</a>  ...]]</string>

Then in code you need to get the string and assign it as HTML and set a link movement method:

String yourText = getString(R.string.your_text);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
   textView.setText(Html.fromHtml(yourText, Html.FROM_HTML_MODE_COMPACT));
} else {
   textView.setText(Html.fromHtml(yourText));
}

try {
   subtext.setMovementMethod(LinkMovementMethod.getInstance());
} catch (Exception e) {
   //This code seems to crash in some Samsung devices.
   //You can handle this edge case base on your needs.
}
Benny
  • 1,650
  • 17
  • 20
6

I had to hunt this down in a couple places, but I finally got this version of the code to work.

File strings.xml:

<string name="name1">&lt;a href="http://www.google.com">link text1&lt;/a></string>
<string name="name2">&lt;a href="http://www.google.com">link text2&lt;/a></string>

File myactivity.xml:

<TextView
    android:id="@+id/textview1"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginTop="5dp" />

<TextView
    android:id="@+id/textview2"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginTop="5dp" />

File myactivty.java (in onCreate()):

TextView tv1 = (TextView)findViewById(R.id.textview1);
TextView tv2 = (TextView)findViewById(R.id.textview2);

tv1.setText(Html.fromHtml(getResources().getString(R.string.name1)));
tv2.setText(Html.fromHtml(getResources().getString(R.string.name2)));
tv1.setMovementMethod(LinkMovementMethod.getInstance());
tv2.setMovementMethod(LinkMovementMethod.getInstance());

This will create two clickable hyperlinks with the text link text1 and link text2 which redirect the user to Google.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
degausser
  • 177
  • 1
  • 3
  • 9
6

The reason you're having the problem is that it only tries to match "naked" addresses. Things like "www.google.com" or "http://www.google.com".

Running your text through Html.fromHtml() should do the trick. You have to do it programmatically, but it works.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeremy Logan
  • 47,151
  • 38
  • 123
  • 143
  • 3
    The links in the TextView are a different color than other text in the string, so I think they're being recognized as links. They're just not clickable :-( – Richard Apr 30 '10 at 17:49
6

Create an extension method on SpannableString:

private fun SpannableString.setLinkSpan(text: String, url: String) {
    val textIndex = this.indexOf(text)
    setSpan(
        object : ClickableSpan() {
            override fun onClick(widget: View) {
                Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) }.also { startActivity(it) }
            }
        },
        textIndex,
        textIndex + text.length,
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
    )
}

Use it to make string in your TextView clickable:

    myTextView.apply {
        movementMethod = LinkMovementMethod.getInstance()

        val googleUrl = "http://www.google.com"
        val microsoftUrl = "http://www.microsoft.com"

        val google = "Google"
        val microsoft = "Microsoft"

        val message = SpannableString("$google & $microsoft").apply {
            setLinkSpan(google, googleUrl)
            setLinkSpan(microsoft, microsoftUrl)
        }

        text = message
    }

Enjoy!

enter image description here

farhanjk
  • 1,652
  • 16
  • 17
  • In case others have the same problem: I had a hard time getting this solution to work, before realizing I had missed the line on movementMethod. Adding it did the trick. – Leknesh Oct 17 '22 at 10:38
5

If using an XML-based TextView, for your requirement you need to do just two things:

  1. Identify your link in the string, such as "this is my WebPage." You can add it in the XML content or in the code.

  2. In the XML content that has the TextView, add these:

     android:linksClickable="true"
    
     android:autoLink="web"
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
codeFood
  • 1,241
  • 16
  • 16
5

Add CDATA to your string resource

Strings.xml

<string name="txtCredits"><![CDATA[<a href=\"http://www.google.com\">Google</a>]]></string>
Akexorcist
  • 2,287
  • 1
  • 16
  • 19
5

I just wasted so much time to figure out you have to use getText(R.string.whatever) instead of getString(R.string.whatever)...

Anyway, here is how I got mine working. With multiple hyperlinks in the same text view too.

TextView termsTextView = (TextView) getActivity().findViewById(R.id.termsTextView);
termsTextView.append("By registering your account, you agree to our ");
termsTextView.append(getText(R.string.terms_of_service));
termsTextView.append(", ");
termsTextView.append(getText(R.string.fees));
termsTextView.append(", and the ");
termsTextView.append(getText(R.string.stripe_connected_account_agreement));

termsTextView.setMovementMethod(LinkMovementMethod.getInstance());

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/termsTextView"/>

String example:

    <string name="stripe_connected_account_agreement"><a href="https://stripe.com/connect/account-terms">Stripe Connected Account Agreement</a></string>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
luca992
  • 1,548
  • 22
  • 27
  • 1
    This is so much more straight-forward and easy to use. I have multiple links with custom text working in a dynamically added TextView because of this. This needs the most upvotes possible. Been breaking my head over Spanned strings, custom TextViews and HtmlCompat.fromHtml methods. Thank you so much @luca992. – Parth Patel Nov 30 '19 at 05:26
4

Autolink phone did not work for me. The following worked like a charm,

TextView tv = (TextView) findViewById(R.id.emergencynos);
String html2="<br><br>Fire - <b><a href=tel:997>997</a> </b></br></br>";
tv.append(Html.fromHtml(html2));
tv.setMovementMethod(LinkMovementMethod.getInstance());
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1995307
  • 697
  • 6
  • 12
3

I use the autolink to "auto underline" the text, but I just made an "onClick" that manages it (I ran into this problem myself).

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="10dp"
    android:textSize="18dp"
    android:autoLink="all"
    android:text="@string/twitter"
    android:onClick="twitter"/>

public void twitter (View view)
{
    try
    {
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://twitter.com/onaclovtech"));
        startActivity(browserIntent);
    }
    finally
    {
    }
}

It doesn't require any permissions, as you are passing the intent off to apps that manage those resources, (i.e., the browser).

This was what worked for me.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
onaclov2000
  • 5,741
  • 9
  • 40
  • 54
  • You are not making a link that is clickable, you are just putting the whole TextView clickable... That's not the question. – clauziere Jan 28 '16 at 17:28
  • Agreed, but sometimes a workaround that works, is the same thing. Clearly 5 years after the most popular answer has been written, this was still a problem, and its been 6 months sice i had the same problem, but ended up with a different but working solution. – onaclov2000 Jan 29 '16 at 12:53
3

My code was like this:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/link"
    android:text="@string/forgot"
    android:layout_marginTop="16dp"
    android:gravity="center"
    android:linksClickable="true"/>

My Java code was like this:

/*TextView action*/
        TextView textView = (TextView) findViewById(R.id.link);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(LoginActivity.this,forgot.class));
            }
        });  

This just points the link to another activity. But that link is clickable and works smoothly. Tested in Android Studio 1.5 (Preview)

Ajay Kulkarni
  • 2,900
  • 13
  • 48
  • 97
1

Use this:

package com.stackoverflow.java.android;

import android.content.Context;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;

public class HyperlinkTextView extends AppCompatTextView {
    public HyperlinkTextView(Context context) {
        super(context);
    }

    public HyperlinkTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public HyperlinkTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * Set default movement method to {@link LinkMovementMethod}
     * @return Link movement method as the default movement method
     */
    @Override
    protected MovementMethod getDefaultMovementMethod() {
        return LinkMovementMethod.getInstance();
    }
}

Now, simply using com.stackoverflow.java.android.HyperlinkTextView instead of TextView in your layout files will solve your problem.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Muntashir Akon
  • 8,740
  • 2
  • 27
  • 38
1

For those who are having issues with strings reading from XML content and assigning dynamically.

In case you are using text from a strings.xml resource, it seems that the HTML tags gets stripped out.

So you have to use <![CDATA[**your string with click links**]]> in the strings.xml file to convert it to HTML using Html.fromHtml(string).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Monster Brain
  • 1,950
  • 18
  • 28
  • Could you please give an example, I have this error. For example, how to convert this in order to use with dynamically content: %1$s hello google – Andrew Aug 03 '21 at 18:01
  • 1
    @Andrew - You can use strings inside cdata like this <![CDATA[%1$s Check google]]> then replace with val replacedString = String.format(getString(R.string.sample_html), "Tada..") and set from Html textViewHtml.text = Html.fromHtml(replacedString, Html.FROM_HTML_MODE_LEGACY) also add to make it clickable textViewHtml.movementMethod = LinkMovementMethod.getInstance() --- (Your google link was not correct .. add https ) – Monster Brain Aug 04 '21 at 06:03
1

In kotlin you can do

binding.yourTextView.movementMethod = LinkMovementMethod.getInstance()

your string should be in HTML format

Swapnil
  • 121
  • 7
0

As the databinding is out, I'd like to share my solution for databinding TextViews supporting HTML tags with clickable links.

To avoid retrieving every textview and giving them html support using From.html we extend the TextView and put the logic in setText()

public class HtmlTextView extends TextView {

    public HtmlTextView(Context context) {
        super(context);
    }

    public HtmlTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(Html.fromHtml(text.toString()), type);
        this.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

I've made a gist which also shows example entity and view for using this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
J.G.Sebring
  • 5,934
  • 1
  • 31
  • 42
0

You can simply add links to your TextView with Android's Linkify library.

Add to your strings.xml

<string name="text_legal_notice">By continuing, you confirm that you have read, understood and agreed to our %1$s and %2$s.</string>
<string name="text_terms_conditions">Terms &amp; Conditions</string>
<string name="text_privacy_policy">Privacy Policy</string>

Add to your activity

final String termsConditionsText = getString(R.string.text_terms_conditions);
final String privacyPolicyText = getString(R.string.text_privacy_policy);
final String legalText = getString(
        R.string.text_legal_notice,
        termsConditionsText,
        privacyPolicyText
);
viewBinding.textViewLegalNotice.setText(legalText);

Linkify.addLinks(
        viewBinding.textViewLegalNotice,
        Pattern.compile(termsConditionsText),
        null,
        null,
        (match, url) -> "https://policies.google.com/terms"
);
Linkify.addLinks(
        viewBinding.textViewLegalNotice,
        Pattern.compile(privacyPolicyText),
        null,
        null,
        (match, url) -> "https://policies.google.com/privacy"
);
Atakan Yildirim
  • 684
  • 11
  • 22
0

Not to beat this to death, but here is what is happening under the covers with Linkfy, etc. You'll notice that setText() takes a CharSequence. Linkify, etc. converts the String to Spannable and adds Spans. Spannable indirectly inherits from CharSequence, just like String, so it works with setText(). With Spannables you can mix and match Spans and do all sorts of interesting things. Here's a simple example.

val textView = findViewById<TextView>(R.id.myTextView)
val span = SpannableStringBuilder(getString(R.string.linkText))
textView [0, textView .length] = URLSpan("https://myWebiste.com/")
textView.text = span
textView.movementMethod = LinkMovementMethod.getInstance()

Just a note, the Kotlin syntax is very slick but it obfuscates the Spannable.setSpan() call, which is where the magic happens.

Dustin
  • 2,064
  • 1
  • 16
  • 12
0

Simple Solution using Kotlin Programming Language

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
    android:id="@+id/linear1"
    android:orientation="vertical"
    >
    <TextView
        android:id="@+id/txtWeb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:layout_margin="5dp"
        android:padding="5dp"
        android:layout_gravity="fill_horizontal"
        />
    <TextView
        android:id="@+id/txtEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:layout_margin="5dp"
        android:padding="5dp"
        android:layout_gravity="fill_horizontal"
        />

    <TextView
        android:id="@+id/txtPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:layout_margin="5dp"
        android:padding="5dp"
        android:layout_gravity="fill_horizontal"
        />
</LinearLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val tvWeb = findViewById<TextView>(R.id.txtWeb)
        val tvEmail = findViewById<TextView>(R.id.txtEmail)
        val tvPhone = findViewById<TextView>(R.id.txtPhone)

        //for web address
        tvWeb.setText("Please visit us: www.google.com")
        Linkify.addLinks(tvWeb, Linkify.WEB_URLS)

        //for email address
        tvEmail.setText("Please Email Us:abcdef@gmail.com")
        Linkify.addLinks(tvEmail,Linkify.EMAIL_ADDRESSES)

        //for phone number
        tvPhone.setText("Please Call Us: +4672123456")
        Linkify.addLinks(tvPhone,Linkify.PHONE_NUMBERS)
    }
}
Ashraf Gardizy
  • 357
  • 4
  • 9