Android TextView with Clickable Links: how to capture clicks? Android TextView with Clickable Links: how to capture clicks? android android

Android TextView with Clickable Links: how to capture clicks?


Based upon another answer, here's a function setTextViewHTML() which parses the links out of a HTML string and makes them clickable, and then lets you respond to the URL.

protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span){    int start = strBuilder.getSpanStart(span);    int end = strBuilder.getSpanEnd(span);    int flags = strBuilder.getSpanFlags(span);    ClickableSpan clickable = new ClickableSpan() {        public void onClick(View view) {            // Do something with span.getURL() to handle the link click...        }    };    strBuilder.setSpan(clickable, start, end, flags);    strBuilder.removeSpan(span);}protected void setTextViewHTML(TextView text, String html){    CharSequence sequence = Html.fromHtml(html);    SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);    URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);       for(URLSpan span : urls) {        makeLinkClickable(strBuilder, span);    }    text.setText(strBuilder);    text.setMovementMethod(LinkMovementMethod.getInstance());       }


I made an easy extension function in Kotlin to catch url link clicks in a TextView by applying a new callback to URLSpan elements.

strings.xml (example link in text)

<string name="link_string">this is my link: <a href="https://www.google.com/">CLICK</a></string>

Make sure your spanned text is set to the TextView before you call "handleUrlClicks"

textView.text = getString(R.string.link_string)

This is the extension function:

/** * Searches for all URLSpans in current text replaces them with our own ClickableSpans * forwards clicks to provided function. */fun TextView.handleUrlClicks(onClicked: ((String) -> Unit)? = null) {    //create span builder and replaces current text with it    text = SpannableStringBuilder.valueOf(text).apply {        //search for all URL spans and replace all spans with our own clickable spans        getSpans(0, length, URLSpan::class.java).forEach {            //add new clickable span at the same position            setSpan(                object : ClickableSpan() {                    override fun onClick(widget: View) {                        onClicked?.invoke(it.url)                    }                },                getSpanStart(it),                getSpanEnd(it),                Spanned.SPAN_INCLUSIVE_EXCLUSIVE            )            //remove old URLSpan            removeSpan(it)        }    }    //make sure movement method is set    movementMethod = LinkMovementMethod.getInstance()}

This is how I call it:

textView.handleUrlClicks { url ->    Timber.d("click on found span: $url")}


You've done as follows:

text_view.setMovementMethod(LinkMovementMethod.getInstance());text_view.setText( Html.fromHtml( str_links ) );

have you tried in reverse order as shown below?

text_view.setText( Html.fromHtml( str_links ) );text_view.setMovementMethod(LinkMovementMethod.getInstance());

and without:

text_view.setLinksClickable(true);