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.
Navigate to the app > res > layout > activity_main. xml and add the below code to that file. Below is the code for the activity_main. xml file.
<a href=” “> helps one to specify the target. This is followed by adding the text that is clickable in HTML. For example, in the above example, https://testbook.com/ is the link that is attached to the text “Testbook website page”. Finally, to finish it, you can add the </a> tag to indicate where the link ends.
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)
}
`
textViewLink.colorSpannableStringWithUnderLineOne(
"Normal string",
"Clickable string",
callback = {
JLog.e("==>","Clicked")
})
textViewLink.invalidate()
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With