1
+ package com.flyjingfish.formattextview
2
+
3
+ import android.content.Context
4
+ import android.graphics.Color
5
+ import android.text.Html
6
+ import android.text.SpannableStringBuilder
7
+ import android.text.method.LinkMovementMethod
8
+ import android.text.style.ClickableSpan
9
+ import android.text.style.URLSpan
10
+ import android.text.util.Linkify
11
+ import android.util.AttributeSet
12
+ import android.view.View
13
+ import androidx.appcompat.widget.AppCompatTextView
14
+
15
+ class HtmlTextView : AppCompatTextView {
16
+ private var onHtmlClickListener: OnHtmlClickListener ? = null
17
+ private var isClickSpanItem = false
18
+ constructor (context: Context ? ) : super (context)
19
+ constructor (context: Context ? , attrs: AttributeSet ? ) : super (context, attrs)
20
+ constructor (context: Context ? , attrs: AttributeSet ? , defStyleAttr: Int ) : super (
21
+ context,
22
+ attrs,
23
+ defStyleAttr
24
+ )
25
+
26
+ fun setHtmlText (htmlText : String ) {
27
+ setHtmlText(htmlText, false )
28
+ }
29
+
30
+ fun setHtmlText (htmlText : String , isDeleteWrap : Boolean ) {
31
+ text = setClickableHtml(htmlText, isDeleteWrap)
32
+ highlightColor = Color .TRANSPARENT
33
+ autoLinkMask = Linkify .WEB_URLS
34
+ }
35
+
36
+ private fun setClickableHtml (webText : String , isDeleteWrap : Boolean ): CharSequence? {
37
+ val spanned = Html .fromHtml(webText)
38
+ var htmlBuilder = SpannableStringBuilder (spanned)
39
+ if (isDeleteWrap) {
40
+ htmlBuilder = deleteLines(htmlBuilder)
41
+ }
42
+ val spans = htmlBuilder.getSpans(
43
+ 0 , spanned.length,
44
+ URLSpan ::class .java
45
+ )
46
+ for (i in spans.indices) {
47
+ val span = spans[i]
48
+ setSpanClickable(htmlBuilder, span)
49
+ }
50
+ return htmlBuilder
51
+ }
52
+
53
+ private fun setSpanClickable (htmlBuilder : SpannableStringBuilder , urlSpan : URLSpan ) {
54
+ val start = htmlBuilder.getSpanStart(urlSpan)
55
+ val end = htmlBuilder.getSpanEnd(urlSpan)
56
+ val flags = htmlBuilder.getSpanFlags(urlSpan)
57
+ val clickableSpan: ClickableSpan = object : ClickableSpan () {
58
+ override fun onClick (widget : View ) {
59
+ val url = urlSpan.url
60
+ if (onHtmlClickListener != null ) {
61
+ onHtmlClickListener!! .onLabelClick(url)
62
+ isClickSpanItem = true
63
+ }
64
+ }
65
+ }
66
+ htmlBuilder.setSpan(clickableSpan, start, end, flags)
67
+ }
68
+
69
+ fun deleteLines (spannableStringBuilder : SpannableStringBuilder ): SpannableStringBuilder {
70
+ val length = spannableStringBuilder.length
71
+ for (i in 0 until length) {
72
+ val ch = spannableStringBuilder[i]
73
+ if (ch == ' \r ' || ch == ' \n ' ) {
74
+ return deleteLines(spannableStringBuilder.delete(i, i + 1 ))
75
+ }
76
+ }
77
+ return spannableStringBuilder
78
+ }
79
+
80
+
81
+ interface OnHtmlClickListener {
82
+ fun onLabelClick (url : String? )
83
+ }
84
+
85
+ override fun setOnClickListener (l : OnClickListener ? ) {
86
+ super .setOnClickListener { v: View ? ->
87
+ if (! isClickSpanItem && l != null ) {
88
+ l.onClick(this @HtmlTextView)
89
+ }
90
+ isClickSpanItem = false
91
+ }
92
+ }
93
+
94
+ fun setOnHtmlClickListener (onHtmlClickListener : OnHtmlClickListener ? ) {
95
+ movementMethod = LinkMovementMethod .getInstance()
96
+ this .onHtmlClickListener = onHtmlClickListener
97
+ }
98
+ }
0 commit comments