Rich text of TextView

It is more common to use rich text in the project. One line displays text in multiple styles and colors. ClickableSpan rich text is used to realize the diversification and personalization of the text color, size, background color and other attributes in the same TextView.

We can also use Html.fromHtml (string) to write text format, need to pay attention to :
1. When the string is too large, it will throw IOException
2.Html.fromHtml (string) will replace the '\ r' and '\ n' in the string with spaces, so we need to explicitly replace it with the html-recognizable '<br>' otherwise an IOException
3. Android native only supports some html tag tags
 

Problems encountered when using ClickableSpan :

Use ClickableSpan to set the response event to the text in the TextView, and then set the response event to the TextView. When you click the ClickableSpan, two events will be triggered at the same time.
Common cases: comment reply, click on the text, a dialog box pops up, click on the nickname, enter the user homepage (friend circle comment reply)
the reason:
1. Check the source code to know that for TextView setMovementMethod, the onTouchEvent method of LinkMovementMethod will also trigger its own onClick event and return to the view for processing. At this time, the TextView also consumes the event, so it will trigger 2 events.
2. TextView setMovementMethod method, the following three methods are set to true by default, according to Android's event distribution mechanism, TextView will also consume the event.
setFocusable(true); setClickable(true); setLongClickable(true);

How to solve:

In the above example, we can disable the click event of the TextView. When the text is clicked, it is handed over to the parent class for processing. Click the nickname and ClickableSpan to enter the user homepage
1.  Rewrite LinkMovementMethod to return onTouchEvent as false.
2. TextView is not clickable.
setFocusable(false);
setClickable (false);
setLongClickable (false);
 
 
Problem code :

 

 Click ClickableSpan, log output:

 

Modified code:

ClickableMovementMethod modification:

class ClickableMovementMethod : LinkMovementMethod() {

    companion object {
        val mInstance by lazy(LazyThreadSafetyMode.NONE){
            ClickableMovementMethod()
        }

    }

    override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
        val action = event.action

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
            var x = event.x.toInt()
            var y = event.y.toInt()

            x -= widget.totalPaddingLeft
            y -= widget.totalPaddingTop

            x += widget.scrollX
            y += widget.scrollY

            val layout = widget.layout
            val line = layout.getLineForVertical(y)
            val off = layout.getOffsetForHorizontal(line, x.toFloat())

            val links = buffer.getSpans(off, off, ClickableSpan::class.java)

            if (links.size != 0) {
                val link = links[0]
                if (action == MotionEvent.ACTION_UP) {
                    link.onClick(widget)
                } else if (action == MotionEvent.ACTION_DOWN) {

                    Selection.setSelection(
                        buffer,
                        buffer.getSpanStart(link),
                        buffer.getSpanEnd(link)
                    )
                }
                return true
            } else {
                Selection.removeSelection(buffer)
            }
        }
        return false
    }


}
View Code
 
Log output:
 Click ClickableSpan:

Click on the text:

 

 

Reference link:

Guess you like

Origin www.cnblogs.com/fangg/p/12752623.html