Make a string clickable, underlined in a TextView

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

you can define in your strings.xml

<string name="submitText">Before you submit, please check out <a href="actual url">this link</a>

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)


 <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