How to make links in a TextView clickable

AndroidHyperlinkTextviewClickable

Android Problem Overview


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"></TextView>

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.

Android Solutions


Solution 1 - Android

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().

Solution 2 - Android

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.

Solution 3 - Android

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.

Solution 4 - Android

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.

Solution 5 - Android

I simply used this:

Linkify.addLinks(TextView, Linkify.ALL);

It makes the links clickable, given here.

Solution 6 - Android

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...

Solution 7 - Android

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.

Solution 8 - Android

I added this line to the TextView: android:autoLink="web"
Below is an example of usage in a layout file.

layout.xml sample

    <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:[email protected]?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>

Solution 9 - Android

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());

Solution 10 - Android

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.

Solution 11 - Android

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"/>

Solution 12 - Android

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>

Solution 13 - Android

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

Solution 14 - Android

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;

Solution 15 - Android

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

Solution 16 - Android

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.

Solution 17 - Android

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.

Solution 18 - Android

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

Solution 19 - Android

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" />

Solution 20 - Android

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"/>

Solution 21 - Android

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>"));
}

Solution 22 - Android

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

Solution 23 - Android

[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.
}

Solution 24 - Android

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.

Solution 25 - Android

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.

Solution 26 - Android

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"
    

Solution 27 - Android

Add CDATA to your string resource

Strings.xml

<string name="txtCredits"><![CDATA[<a href=\"http://www.google.com\">Google</a>]]></string>

Solution 28 - Android

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>

Solution 29 - Android

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());

Solution 30 - Android

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

Solution 31 - Android

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.

Solution 32 - Android

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)

Solution 33 - Android

Add this in your edittext:

        android:autoLink="web"
        android:linksClickable="true"

Solution 34 - Android

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.

Solution 35 - Android

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

Solution 36 - Android

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - AndroidRichardView Answer on Stackoverflow
Solution 2 - AndroidJanuszView Answer on Stackoverflow
Solution 3 - AndroidJeshurunView Answer on Stackoverflow
Solution 4 - AndroidBłażej CzappView Answer on Stackoverflow
Solution 5 - Androidjai_bView Answer on Stackoverflow
Solution 6 - AndroidvizZView Answer on Stackoverflow
Solution 7 - AndroidAsesha GeorgeView Answer on Stackoverflow
Solution 8 - AndroidShanewajView Answer on Stackoverflow
Solution 9 - AndroidBebin T.NView Answer on Stackoverflow
Solution 10 - AndroidPraveshView Answer on Stackoverflow
Solution 11 - AndroidAhmed MostafaView Answer on Stackoverflow
Solution 12 - AndroidDavid DimalantaView Answer on Stackoverflow
Solution 13 - AndroidKeshav GeraView Answer on Stackoverflow
Solution 14 - AndroidDeathRsView Answer on Stackoverflow
Solution 15 - AndroidRahul RainaView Answer on Stackoverflow
Solution 16 - AndroidaLearnerView Answer on Stackoverflow
Solution 17 - AndroidKelly McKinnonView Answer on Stackoverflow
Solution 18 - AndroidelevenfiveView Answer on Stackoverflow
Solution 19 - AndroidAndrodosView Answer on Stackoverflow
Solution 20 - AndroidTejView Answer on Stackoverflow
Solution 21 - AndroidDominicView Answer on Stackoverflow
Solution 22 - AndroidPhuc TranView Answer on Stackoverflow
Solution 23 - AndroidBennyView Answer on Stackoverflow
Solution 24 - AndroiddegausserView Answer on Stackoverflow
Solution 25 - AndroidJeremy LoganView Answer on Stackoverflow
Solution 26 - AndroidcodeFoodView Answer on Stackoverflow
Solution 27 - AndroidAkexorcistView Answer on Stackoverflow
Solution 28 - Androidluca992View Answer on Stackoverflow
Solution 29 - Androiduser1995307View Answer on Stackoverflow
Solution 30 - AndroidfarhanjkView Answer on Stackoverflow
Solution 31 - Androidonaclov2000View Answer on Stackoverflow
Solution 32 - AndroidAjay KulkarniView Answer on Stackoverflow
Solution 33 - AndroidPrograminerView Answer on Stackoverflow
Solution 34 - AndroidMuntashir AkonView Answer on Stackoverflow
Solution 35 - AndroidMonster BrainView Answer on Stackoverflow
Solution 36 - AndroidJ.G.SebringView Answer on Stackoverflow