上班时,公司业务逻辑正好需要,顺手写得,目前只能在一串文本中加入一个可点击字符串。
/**
* 适用于为TextView设置点击事件,且可以在点击文字后继续显示不被点击的文字
* 不适用于一串文字中含有多处点击事件
* @param start 点击文字的开始
* @param end 点击文字的结束。不传递时默认为文字的末尾
* @param color 可点击文字的颜色,默认为蓝色
* @param setText 设置文本,如果不传递,则直接使用textView的字体
* @param click 点击事件回调
*/
fun TextView.setClickText(
start: Int,
end: Int = -1,
color: Int = Color.BLUE,
setText: String = "",
click: (View) -> Unit,
) {
val text = if (setText.isBlank()) text.toString() else setText
val endIndex = if (end == -1) text.length else end
val unText = text.subSequence(0, start).toString()
val clickText = text.subSequence(start, endIndex).toString()
val overText =
if (endIndex < text.length) text.subSequence(endIndex, text.length).toString() else ""
setClickText(unText, clickText, color, overText, click)
}
/**
* 不适用一串文字中有多处点击
* @param unText 不被点击的文字
* @param clickText 被点击的文字
* @param color 可点击文字的颜色,默认为蓝色
* @param overText 被点击后剩余的文字
* @param click 点击事件回调
*/
fun TextView.setClickText(
unText: String,
clickText: String,
color: Int = Color.BLUE,
overText: String = "",
click: (View) -> Unit
) {
val annotatedText = buildSpannedString {
val text = unText + clickText
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
click(widget)
}
override fun updateDrawState(ds: TextPaint) {
// 可点击文本不要有下划线
ds.isUnderlineText = false
ds.color = ds.linkColor
}
}
val foreColor = ForegroundColorSpan(color)
append(text)
setSpan(clickableSpan, unText.length, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
setSpan(foreColor, unText.length, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
if (overText.isNotBlank()) {
append(overText)
}
}
movementMethod = LinkMovementMethod.getInstance()
text = annotatedText
}