使用扩展函数为 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 = {
                //点击个人信息保护政策
            }
        )
    )
)

三、典型应用场景

  • 用户协议/隐私政策条款
  • 文本中的超链接
  • 可点击的免责声明
  • 动态生成的带操作提示文本
相关推荐
alexhilton6 小时前
将应用迁移到Navigation 3:痛点、加班和紧急修复
android·kotlin·android jetpack
杉氧11 小时前
Navigation Compose 深度实践:如何优雅地串联起你的全栈 App?
android·架构·android jetpack
唐青枫13 小时前
Kotlin 运算符重载详解:为什么 a += b 有时改对象,有时换对象?
kotlin
雨白15 小时前
指针与数组的核心机制
android
黄林晴19 小时前
Room 3.0 正式发布!包名彻底重构,KMP 成为核心主线
android·android jetpack
三少爷的鞋20 小时前
Kotlin 协程环境下的 DCL 懒加载:别把线程时代的经验直接搬过来
android
plainGeekDev20 小时前
Gson → kotlinx.serialization
android·java·kotlin
CYY951 天前
Compose 入门篇
android·kotlin
杉氧2 天前
Compose 时代的 MVI 架构:如何用单向数据流驱动复杂 UI?
android·架构·android jetpack