使用扩展函数为 AppCompatTextView 提供了多段文本点击区域设置功能

使用 Kotlin 扩展函数为 AppCompatTextView 提供了多段文本点击区域设置功能,允许在单个文本视图中设置多个可点击区域,每个区域可独立设置点击事件和文字颜色。

一、核心代码

1、ClickablePart 数据结构

kotlin 复制代码
data class ClickablePart(
    val targetText: String, // 需要高亮点击的文本
    val linkColor: Int? = null, // 高亮颜色
    val onClick: () -> Unit // 点击回调
)

1、扩展函数

kotlin 复制代码
import android.graphics.Color
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import com.hongtu.utils.entity.ClickablePart
import kotlin.collections.forEach

/**
 * 扩展函数:简化多段文本点击设置
 * @param fullText 全部文本
 * @param clickableParts 多段文本点击区域
 * @param linkColor 点击区域文字颜色
 */
fun AppCompatTextView.setMultiClickableSpan(
    fullText: String,
    clickableParts: List<ClickablePart>,
    linkColor: Int = R.color.utils_link_color
) {
    val spannable = SpannableStringBuilder(fullText)

    clickableParts.forEach { part ->
        val startIndex = fullText.indexOf(part.targetText)
        if (startIndex == -1) return@forEach

        val endIndex = startIndex + part.targetText.length

        // 设置点击事件
        spannable.setSpan(
            object : ClickableSpan() {
                override fun onClick(widget: View) = part.onClick()
                override fun updateDrawState(ds: TextPaint) {
                    ds.color = ds.linkColor
                    ds.isUnderlineText = false
                }
            },
            startIndex,
            endIndex,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        // 设置文字颜色
        spannable.setSpan(
            ForegroundColorSpan(part.linkColor?:ContextCompat.getColor(context, linkColor)),
            startIndex,
            endIndex,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }

    // 配置TextView
    movementMethod = LinkMovementMethod.getInstance()
    highlightColor = Color.TRANSPARENT
    text = spannable
}

二、使用示例

kotlin 复制代码
binding.tvAgreement.setMultiClickableSpan(
    fullText = "已阅读并同意《用户服务协议》、《个人信息保护政策》",
    clickableParts = listOf(
        ClickablePart(
            targetText = "已阅读并同意",
            onClick = {
                //选中CheckBox
            },
            linkColor = ContextCompat.getColor(this, R.color.design_white)
        ),
        ClickablePart(
            targetText = "《用户服务协议》",
            onClick = {
                //点击用户服务协议
            }
        ),
        ClickablePart(
            targetText = "《个人信息保护政策》",
            onClick = {
                //点击个人信息保护政策
            }
        )
    )
)

三、典型应用场景

  • 用户协议/隐私政策条款
  • 文本中的超链接
  • 可点击的免责声明
  • 动态生成的带操作提示文本
相关推荐
执明wa10 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
404_coder10 小时前
源码视角下的 Android 开机流程:从 Zygote、SystemServer 到 Launcher
android
二流小码农10 小时前
鸿蒙开发:以登录案例了解代码架构MVVM
android·ios·harmonyos
用户693717500138411 小时前
从代码生产者到 AI 协作者:软件工程师的角色重构
android·前端·后端
GitLqr11 小时前
别在 Flutter 的 main() 里乱锁屏幕方向,小心 iPad 分屏功能被你搞没了
android·flutter·ios
sg_knight11 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
爱笑鱼11 小时前
Binder(四):ioctl(BINDER_WRITE_READ) 之后,事务怎样到达目标进程?
android
AFinalStone12 小时前
Android 7系统休眠唤醒(二)开机全链路—BootROM到Launcher
android·电源管理·休眠唤醒
Mr YiRan12 小时前
Android NDK开发之统计到未被回收的图片
android