Cannot format partial TextView or Button text in Android Studio - android

I'm using Android Studio to create an English language learning app and I want to make a few letters on a button bold but I cannot do it. For example I want the button to read "I like basketball" as the first syllable in basketball is emphasized when we pronounce the word.
However I cannot get this to work. Here is my strings.xml.
<string name="test">I like <b>bas</b>ketball</string>
And here is my activity.xml.
<Button
android:id="#+id/test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/test"
android:textAllCaps="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+string/test"
android:textAllCaps="false" />
</LinearLayout>
Neither the Button nor the TextView are recognizing the formatting.
I will have over 400 buttons that will require a different set of characters to be bold so I don't want to use spannable strings to code this.
Is there an easy solution?

1st Approach-
you string need to be updated to <string name="test">I like <b> bas</b>ketball.</string> if you are using string from String.xml
but you need to add below code in Activity class to work -
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(getString(R.string.test), Html.FROM_HTML_MODE_LEGACY));
}else{
textView.setText(Html.fromHtml(getString(R.string.test));
}
2nd Approach-
Add below code in your String.xml file at top
<?xml version="1.0" encoding="utf-8"?>
Then add your string in resources -
<resources>
<string name="test"><![CDATA[I like <b> bas</b>ketball]]></string>
</resources>
and then in activity class set the HTML text like below -
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(getString(R.string.test), Html.FROM_HTML_MODE_LEGACY));
}else{
textView.setText(Html.fromHtml(getString(R.string.test));
}
Hope this will help.

Related

How to creat a clickable link in a textview?

I am trying to create a clickable link in a textview in a fragment. I think the emulator sees my string as a link but I can't make it clickable. Any suggestions?
In xml
<TextView
android:id="#+id/textViewLink"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:clickable="true"
android:linksClickable="true"
android:text="#string/link_to_the_website"
android:textColor="#329da8"
android:textSize="17sp" />
In fragment
linkText.setMovementMethod(LinkMovementMethod.getInstance());
linkText.setText(Html.fromHtml(" Read more here"));
linkText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
linkText = v.findViewById(R.id.textViewLink);
linkText.setMovementMethod(LinkMovementMethod.getInstance());
linkText.setText(Html.fromHtml(" Read more here"));
}
});
In strings.xml
<string name="link_to_the_website">
Read more here
</string>
Simply remove android:autoLink="all" and it should work. When you use setMovementMethod, android:autoLink is not needed as it will override the setMovementMethod.
Also I'm not sure why you are setting the TextViews link in 3 different ways remove the:
Using #string on the XML
Programmatically via code
In the onClick
Firstly I don't think the onClick is needed and secondly pick a choice either set it via
android:text="#string/link_to_the_website"
OR
linkText.setText(Html.fromHtml(" Read more here"));
and not both.
If you use the programmatic method thefromHtml method you are using is deprecated you should instead use fromHtml(String source, int flags) like this:
linkText.setText(Html.fromHtml("<a href=https://google.com> Read more here</a>", Html.FROM_HTML_MODE_LEGACY));
notice the extra parameter Html.FROM_HTML_MODE_LEGACY
or like this if you are targeting devices less than Android Nougat (API Level 24):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
linkText.setText(Html.fromHtml("<a href=https://google.com> Read more here</a>", Html.FROM_HTML_MODE_LEGACY));
} else {
linkText.setText(Html.fromHtml("<a href=https://google.com> Read more here</a>"));
}
Lastly I'm not sure linking to a hardcoded path on your C dive will work, I tested the above using an actual website i.e.:
linkText.setText(Html.fromHtml("<a href=https://google.com> Read more here</a>", Html.FROM_HTML_MODE_LEGACY));

How do I set phone numbers to be LTR in a RTL TextView with RTL characters

As you can see here, the phone number here is starting from the right to the left.
However, I want it to display it like this (Image here is edited):
This is the TextView displaying this message:
<TextView
android:text="#string/smsSentTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/smsSentTo"
android:textColor="#color/mdtp_white"
android:textSize="18sp"
android:layout_above="#+id/chooseUsernameAndPickProfilePicture"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"/>
#string/smsSentTo (Arabic locale): (looks like StackOverflow is displaying the {0} wrong, ignore that.)
<string name="smsSentTo">تم إرسال رسالة SMS إلى {0}</string>
#string/smsSentTo (English locale):
<string name="smsSentTo">An SMS has been sent to {0}</string>
As you can see, I'm formatting the text using MessageFormat:
String smsSentTo = MessageFormat.format(smsSentToTV.getText().toString(), phone);
smsSentToTV.setText(smsSentTo);
How can I get it to display these properly?
There is a solution with a downside
String html = "<p>تم إرسال رسالة SMS إلي</p>" + "+961 01 234 567";
textView.setText(Html.fromHtml(html));
The downside is that the HTML p tag prints a line afterwards separating the number into the next line. I tried to remove it with some HTML attributes or using tags other than p tag, but that didn't work
Hope this satisfies your need, or can give you even a clue.

Android: html in strings.xml

I would like display for example this html code:
<body>
<p><b>Hello World</b></p>
<p>This is a test of the URL Example</p>
<p><b>This text is bold</b></p>
<p><em>This text is emphasized</em></p>
<p><code>This is computer output</code></p>
<p>This is<sub> subscript</sub> and <sup>superscript</sup></p>
</body>
I want to display it on a Dialog by declaring html in resources strings.xml. How can I do it?
The best way to add html source code in strings.xml is to use <![CDATA[html source code]]>. Here is an example:
<string name="html"><![CDATA[<p>Text</p>]]></string>
Then you can display this html in TextView using:
myTextView.setText(Html.fromHtml(getString(R.string.html)));
If you have links in your html and you want them to be clickable, use this method:
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
Here's most of the examples. I don't think the pre tag is supported.
This is the strings.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Formatting</string>
<string name="link"><b>Hello World</b> This is a test of the URL <a href="http://www.example.com/">Example</a></string>
<string name="bold"><b>This text is bold</b></string>
<string name="emphasis"><em>This text is emphasized</em></string>
<string name="sup">This is <sub>subscript</sub> and <sup>superscript</sup></string>
</resources>
Here's the layout. Note for the link to actually be clickable, there's a bit of extra work needed:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/test1"
android:linksClickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="#+id/test2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="#+id/test3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="#+id/test4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
</ScrollView>
Finally, the code:
TextView test1 = (TextView)findViewById(R.id.test1);
Spanned spanned = Html.fromHtml(getString(R.string.link));
test1.setMovementMethod(LinkMovementMethod.getInstance());
test1.setText(spanned);
TextView test2 = (TextView)findViewById(R.id.test2);
test2.setText(Html.fromHtml(getString(R.string.bold)));
TextView test3 = (TextView)findViewById(R.id.test3);
test3.setText(Html.fromHtml(getString(R.string.emphasis)));
TextView test4 = (TextView)findViewById(R.id.test4);
test4.setText(Html.fromHtml(getString(R.string.sup)));
String.xml can contains HTML entities, like so:
<resources>
<string name="hello_world"><span></string>
</resources>
In your code: getResources().getString(R.string.hello_world); will evaluate to "<span>". You can use this HTML formatted text like this:
TextView helloWorld = (TextView)findViewById(R.id.hello_world);
helloWorld.setText(Html.fromHtml(getString(R.string.hello_world)));
All the styling supported by the XML resources system is explained in the Android documentation.
String Resources: Formatting and Styling
Anything included there can be used and set directly on TextView. If you need to use further HTML markup, you will need to place raw HTML (with escaped characters for <, > and such) into the resource and load the entire thing in a WebView.
This Worked for me :
<?xml version="1.0" encoding="utf-8"?>
<string name="app_name">Sangamner College</string>
<string name="about_desc"><![CDATA[In order to make higher education available in the rural environment such as of Sangamner, Shikshan Prasarak Sanstha was established in 1960. Sangamner College was established by Shikshan Prasarak Sanstha, Sangamner on 23rd January 1961 on the auspicious occasion of Birth Anniversary of Netaji Subhashchandra Bose.The Arts and Commerce courses were commenced in June 1961 and in June 1965 Science courses were introduced. When Sangamner College was founded forty years ago, in 1961, there was no college available to the rural youth of this region. <br><br></>The college was founded with the aim of upliftment of the disadvantageous rural youth in all respects. On one hand, we are aware of the social circumstances prevailing in the rural area where we are working. So, we offer the elective option to students, which are favourable to the local atmosphere. On the other hand, we want to academically empower the aspiring youth by offering vocational course in Computer Applications to students of Arts & Commerce. B.B.A., B.C.A. and M.C.A. courses were started with the same purpose. “Think globally, act locally” is our guiding Principle.]]></string>

Textview link click in fragment - nothing happen [duplicate]

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 Link text.
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">Google</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.
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().
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.
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 http://www.google.com
Some text http://www.google.com
view.setMovementMethod(LinkMovementMethod.getInstance()); will work with the following (will be highlighted and clickable):
Some text http://www.google.com
Some text http://www.google.com
Some text Go to Google
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.
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:
Google
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.
I simply used this:
Linkify.addLinks(TextView, Linkify.ALL);
It makes the links clickable, given here.
If you want to add an HTML-like link, all you need to do is:
add a resource HTML-like string:
<string name="link">Google</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...
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?
Get it here
</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.
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 support#cleverfinger.com.au</string>
<string name="defaultpassword">User Guide http://www.cleverfinger.com.au/user-guide/</string>
I hope this will help you;
String value = "<html>Visit my blog mysite View myactivity callback</html>";
TextView text = (TextView) findViewById(R.id.text);
text.setText(Html.fromHtml(value));
text.setMovementMethod(LinkMovementMethod.getInstance());
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.
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"/>
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);
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;
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">Google</string>
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);
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.
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.
Be sure to not use setAutoLinkMask(Linkify.ALL) when using setMovementMethod(LinkMovementMethod.getInstance()) and Html.fromHTML() on properly formatted HTML links (for example, Google).
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" />
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"/>
Add this to your EditText:
android:autoLink="web"
android:linksClickable="true"
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>"));
}
Use the below code:
String html = "Your Domain Name"
TextView textview = (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(html));
[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[...Link Title ...]]</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.
}
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!
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.
Add CDATA to your string resource
Strings.xml
<string name="txtCredits"><![CDATA[Google]]></string>
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.
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"
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">Stripe Connected Account Agreement</string>

How to make links in a TextView clickable

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 Link text.
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">Google</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.
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().
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.
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 http://www.google.com
Some text http://www.google.com
view.setMovementMethod(LinkMovementMethod.getInstance()); will work with the following (will be highlighted and clickable):
Some text http://www.google.com
Some text http://www.google.com
Some text Go to Google
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.
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:
Google
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.
I simply used this:
Linkify.addLinks(TextView, Linkify.ALL);
It makes the links clickable, given here.
If you want to add an HTML-like link, all you need to do is:
add a resource HTML-like string:
<string name="link">Google</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...
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?
Get it here
</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.
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 support#cleverfinger.com.au</string>
<string name="defaultpassword">User Guide http://www.cleverfinger.com.au/user-guide/</string>
I hope this will help you;
String value = "<html>Visit my blog mysite View myactivity callback</html>";
TextView text = (TextView) findViewById(R.id.text);
text.setText(Html.fromHtml(value));
text.setMovementMethod(LinkMovementMethod.getInstance());
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.
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"/>
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);
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;
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">Google</string>
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);
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.
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.
Be sure to not use setAutoLinkMask(Linkify.ALL) when using setMovementMethod(LinkMovementMethod.getInstance()) and Html.fromHTML() on properly formatted HTML links (for example, Google).
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" />
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"/>
Add this to your EditText:
android:autoLink="web"
android:linksClickable="true"
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>"));
}
Use the below code:
String html = "Your Domain Name"
TextView textview = (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(html));
[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[...Link Title ...]]</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.
}
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!
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.
Add CDATA to your string resource
Strings.xml
<string name="txtCredits"><![CDATA[Google]]></string>
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.
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"
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">Stripe Connected Account Agreement</string>

Categories

Resources