Reputation: 28911
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.
Upvotes: 1163
Views: 701986
Reputation: 882
You can simply add links to your TextView with Android's Linkify library.
For example, let's add a clickable legal notice TextView to our Activity.
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 & Conditions</string>
<string name="text_privacy_policy">Privacy Policy</string>
Activity class
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"
);
Upvotes: 2
Reputation: 389
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:[email protected]")
Linkify.addLinks(tvEmail,Linkify.EMAIL_ADDRESSES)
//for phone number
tvPhone.setText("Please Call Us: +4672123456")
Linkify.addLinks(tvPhone,Linkify.PHONE_NUMBERS)
}
}
Upvotes: 0
Reputation: 200
In kotlin you can do
binding.yourTextView.movementMethod = LinkMovementMethod.getInstance()
your string should be in HTML format
Upvotes: 2
Reputation: 2154
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.
Upvotes: 0
Reputation: 2107
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:[email protected]?Subject=Lost%20Password" target="_top">[email protected]</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>
Upvotes: 55
Reputation: 319
Add this to your EditText:
android:autoLink="web"
android:linksClickable="true"
Upvotes: 14
Reputation: 2119
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).
Upvotes: 1
Reputation: 9431
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.
Upvotes: 1
Reputation: 11244
Manage Linkify text color also
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);
Upvotes: 25
Reputation: 2268
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.
Upvotes: 70
Reputation: 822
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.
Upvotes: 30
Reputation: 3450
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);
Upvotes: 23
Reputation: 186
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.
Upvotes: 15
Reputation: 5964
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.
Upvotes: 0
Reputation: 1593
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>
Upvotes: 5
Reputation: 5841
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.
Upvotes: 3
Reputation: 1120
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;
Upvotes: 23
Reputation: 2649
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());
Upvotes: 38
Reputation: 8073
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));
Upvotes: 9
Reputation: 1103
I simply used this:
Linkify.addLinks(TextView, Linkify.ALL);
It makes the links clickable, given here.
Upvotes: 89
Reputation: 1251
If using an XML-based TextView, for your requirement you need to do just two things:
Identify your link in the string, such as "this is my WebPage." You can add it in the XML content or in the code.
In the XML content that has the TextView, add these:
android:linksClickable="true"
android:autoLink="web"
Upvotes: 5
Reputation: 747
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());
Upvotes: 4
Reputation: 693
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" />
Upvotes: 12
Reputation: 177
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"><a href="http://www.google.com">link text1</a></string>
<string name="name2"><a href="http://www.google.com">link text2</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.
Upvotes: 6
Reputation: 409
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"/>
Upvotes: 12
Reputation: 1530
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...
Upvotes: 74
Reputation: 379
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"/>
Upvotes: 26
Reputation: 2633
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.:
<a href="http://www.google.com">Google</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.
Upvotes: 110
Reputation: 3473
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>"));
}
Upvotes: 9
Reputation: 28911
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()
.
Upvotes: 1355