Make a string clickable, underlined in a TextView
Solution 1
the problem is that you are setting the span to the whole string (sp.setSpan(click, 0, sp.length()
). To fix you have to set the clickable span only on the this link
. I did the same thing this way:
<string name="submitText">Before you submit, please check out %1$s</string>
<string name="this_link">this link</string>
in your Activity
String thisLink = getString(R.string.thisLink);
String yourString = getString(R.string.submitText, thisLink);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(yourString);
spannableStringBuilder.setSpan(click,
startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
where startIndex and endIndex are the index of thisLink
in yourString
. I separated the two strings because was kind of easier to look for the indexes, especially if you have to deal with translations. To calculate the startIndex you can use yourString.indexOf(thisLink)
, and endIndex is startIndex + the length of thisLink
. I'll leave to you the ordinary checks, (negative indexes, and everything else that could cause an IndexOutBoundException
)
Solution 2
you can define in your strings.xml
<string name="submitText">Before you submit, please check out <a href="actual url">this link</a>
Solution 3
<TextView
android:id="@+id/tvSubmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:autoLink=@String/submitText //link the content of web
android:textColorLink="#576586" //change the color of the link
android:textColor="#555555" />
in activity //sample
String webLinkText = <a href="https://prativas.files.wordpress.com/2013/05/screenshot-mozilla-firefox-private-browsing.png"><img src="https://prativas.files.wordpress.com/2013/05/screenshot-mozilla-firefox-private-browsing.png" alt="Screenshot-Mozilla Firefox (Private Browsing)" width="293" height="254" class="alignnone size-full wp-image-291" /></a>
tvSubmit = (TextView) findViewById(R.id.tvSubmit);
tvSubmit.setText(Html.fromHtml(webLinkText)));
check here for more detailed answer
Solution 4
You can try the Kotlin extension function to create text-like and also clickable with an underline.
fun TextView.colorSpannableStringWithUnderLineOne(
prefixString: String,
postfixString: String,
callback: (Int) -> Unit
) {
val spanTxt = SpannableStringBuilder()
spanTxt.append("$prefixString ")
spanTxt.append(" $postfixString")
spanTxt.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
callback(0)
widget.invalidate()
}
override fun updateDrawState(ds: TextPaint) {
ds.color = ContextCompat.getColor(context, R.color.highlight)
ds.isUnderlineText = true
}
}, prefixString.length, spanTxt.length, 0)
this.movementMethod = LinkMovementMethod.getInstance()
this.setText(spanTxt, TextView.BufferType.SPANNABLE)
}
`
How to use this:
textViewLink.colorSpannableStringWithUnderLineOne(
"Normal string",
"Clickable string",
callback = {
JLog.e("==>","Clicked")
})
textViewLink.invalidate()
Solution 5
In my case i needed to have a localised string with part of it to be clickable. What i did was to define a string in my resources (one for each locale) with the clickable part underlined, like this:
<string name="my_message">Blah blah blah <u>call us</u> blah blah.</string>
Then i created an extension to find the underlined text and add clickable span on it, like this:
fun CharSequence.makeUnderlineClickable(listener: (index: Int) -> Unit): SpannableString {
val spannedString = SpannableString(this)
spannedString.getSpans(0, length, UnderlineSpan::class.java)?.forEachIndexed { index, underlineSpan ->
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
listener.invoke(index)
}
override fun updateDrawState(ds: TextPaint) {
ds.isUnderlineText = true
}
}
spannedString.setSpan(
clickableSpan,
spannedString.getSpanStart(underlineSpan),
spannedString.getSpanEnd(underlineSpan),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
return spannedString
}
You can use it like this:
textView.text = resources.getText(R.string.my_message).makeUnderlineClickable { index ->
//handle click here
}
textView.movementMethod = LinkMovementMethod.getInstance()
textView.highlightColor = Color.TRANSPARENT
Related videos on Youtube
Zbarcea Christian
Updated on September 26, 2022Comments
-
Zbarcea Christian over 1 year
I want to make the string "this link" underlined and clickable, but I don't know how to achieve that.
XML file:
<string name="submitText">Before you submit, please check out <u>this link</u></string>
In my fragment:
tvSubmit.setText(Html.fromHtml(getString(R.string.submitText)));
I don't want the whole string to be clickable, only the underlined section. I cannot use a horizontal
LinearLayout
with 2 cells, because on smaller devices the string won't have a continues look, it will be sectioned in 2 cells.What have I tried:
tvSubmit.setMovementMethod(LinkMovementMethod.getInstance()); Spannable sp = (Spannable) tvSubmit.getText(); ClickableSpan click = new ClickableSpan() { @Override public void onClick(View widget) { showLink(); } }; sp.setSpan(click, 0, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
The code above makes the whole string underlined and also the color of the text is changed into light blue.
-
2Dee about 9 yearsThis has no effect, because the original string doesn't actually contain a url... Read the question carefully.
-
Mobile Team ADR-Flutter about 9 yearsplease check modified answer.
-
latsson almost 3 yearsThanks! Also to make the rest of the textView check the checkbox I added the following textView.setOnClickListener { if (selectionStart == -1 && selectionEnd == -1) { onCheckboxClick() } }