Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a string clickable, underlined in a TextView

enter image description here

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 &lt;u>this link&lt;/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.

like image 365
Zbarcea Christian Avatar asked Apr 02 '15 08:04

Zbarcea Christian


People also ask

How do you underline TextView?

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.

How do I make a string clickable?

<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.


2 Answers

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()
like image 176
Bhojaviya Sagar Avatar answered Sep 29 '22 22:09

Bhojaviya Sagar


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
like image 35
Zacharias Hadjikyprianou Avatar answered Sep 30 '22 00:09

Zacharias Hadjikyprianou