Android 富文本 点击变色、事件传递

开发语言为Kotlin,还在使用java的小朋友,不妨试试

在android中富文本的使用近乎频繁了,网上资料颇多,手上刚好在做一个带有圈子模块的项目

Android 富文本 点击变色、事件传递

贴代码:

自定义类 DefaultClickSpan.kt

import android.support.v4.content.ContextCompat
import android.text.TextPaint
import android.text.style.ClickableSpan
import android.view.View
import android.widget.TextView
import com.qiufeng.educationteacher.R
import com.qiufeng.educationteacher.application.App
import com.qiufeng.educationteacher.ui.listener.ClickListener
import io.reactivex.Flowable
import java.util.concurrent.TimeUnit

class DefaultClickSpan(
        val params: Any? = null,
        val listener: ClickListener? = null,
        val color: Int = -1
) : ClickableSpan() {

    override fun updateDrawState(ds: TextPaint?) {
        super.updateDrawState(ds)
        ds?.let {
        	// 点击文本颜色
            it.color = RUtils.getColor(if (color == -1) R.color.color_blue_grey else color)
            // 去除下划线
            it.isUnderlineText = false
        }
    }
    override fun onClick(widget: View?) {
        widget?.let {
            if (it is TextView) {
            	// 点击时,被点击区域的背景色
                it.highlightColor = RUtils.getColor(R.color.color_grey)
                // 启动一个延时任务,200毫秒后恢复区域颜色
                Flowable.timer(200, TimeUnit.MILLISECONDS).doOnComplete {
                    (widget as TextView).highlightColor = RUtils.getColor(R.color.color_transparent)
                }.subscribe()
            }
            // 点击区域时需要传递的参数
            if (params != null && listener != null) {
                listener.onClick(params)
            }
        }
    }
}

点击事件监听 ClickListener.kt

interface ClickListener {
    fun onClick(any:Any)
}

工具类 RUtils.kt

class RUtils {
    companion object {
        /**
         * 获取资源颜色色值
         * @param rId
         */
        fun getColor(rId: Int): Int {
            return ContextCompat.getColor(App.context, rId)
        }
    }
}

Span工具类:SpannedUtils.kt

class SpannedUtils {
    companion object {
        /**
         * 拼接点击Span
         * @param sb 拼接源
         * @param clickStr 需要拼接的点击文字
         * @param params 点击事件响应返回的数据
         * @param color 拼接字符的前景色
         * @param clickListener 点击事件监听
         */
        fun appendClickableSpan(sb: SpannableStringBuilder,
                                clickStr: String,
                                params: Any? = null,
                                color: Int = -1,
                                clickListener: ClickListener? = null) {
            val oldLength = sb.length
            sb.append(clickStr)
            sb.setSpan(DefaultClickSpan(params, clickListener, color), oldLength, sb.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
    }
}

前端页面调用(使用数据为类似点赞人列表)

private fun setText(list:MutableList<String>){
	val sb = SpannableStringBuilder()
	val length = list.size
	(0 until length){
		SpannedUtils.appendClickableSpan(sb,list[it],list[it],object:ClickListener{
		    override fun onClick(any: Any) {
              showToast(any.toString())      
            }
		})
	}
	// 颜色、回传参数、监听可以不加
	// SpannedUtils.appendClickableSpan(sb,list[it])
	tvHeart.text = sb
	// 这句很重要,否则点击无效
	tvHeart.movementMethod = LinkMovementMethod.getInstance()
}

注释应该够了,可有帮助?