You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现指定下划线文本可点击?

解决仅让下划线协议文本可点击的问题

要实现只有下划线的协议文本可点击,需要替换普通Text为ClickableText,并给每个下划线文本段添加标注来区分点击区域,具体修改如下:

1. 更新调用处的回调参数

把原来的单一回调拆分为两个,分别对应两个下划线文本的点击逻辑:

CheckedBox(
    modifier = Modifier,
    fontSize = 14.sp,
    underlineText1 = "Çerez politikası'nı",
    staticText1 = " ve",
    underlineText2 = " kişisel verilerin korunması kanunu'nu ",
    staticText2 = "okudum ve anladım",
    onUnderlineText1Click = {
        // 这里写展示Cookie政策的逻辑
    },
    onUnderlineText2Click = {
        // 这里写展示个人数据保护法的逻辑
    }
)
CheckedBox(
    modifier = Modifier,
    fontSize = 14.sp,
    underlineText1 = "Kullanıcı sözleşmesi'ni ",
    staticText1 = " ve gizlilik politikasını okudum, anladım ve kabul ediyorum",
    underlineText2 = null,
    staticText2 = null,
    onUnderlineText1Click = {
        // 这里写展示用户协议的逻辑
    },
    onUnderlineText2Click = {} // 第二个下划线文本为空,空实现即可
)

2. 修改CheckedBox组件实现

替换普通Text为ClickableText,并给下划线文本添加标注来识别点击区域:

@Composable
fun CheckedBox(
    modifier: Modifier,
    underlineText1: String,
    fontSize: TextUnit,
    staticText1: String,
    underlineText2: String?,
    staticText2: String?,
    onUnderlineText1Click: () -> Unit,
    onUnderlineText2Click: () -> Unit
) {
    val isCheck = remember { mutableStateOf(false) }
    val color = if (isSystemInDarkTheme()) Color(0xFF1A1818) else Color.White

    val annotatedText = buildAnnotatedString {
        // 给第一个下划线文本添加标注
        appendAnnotation(tag = "UNDERLINE_TEXT_1", annotation = "click")
        withStyle(
            style = SpanStyle(
                textDecoration = TextDecoration.Underline,
                fontSize = fontSize
            )
        ) {
            append(underlineText1)
        }
        appendAnnotation(tag = "UNDERLINE_TEXT_1", annotation = "end")

        // 静态文本1
        withStyle(style = SpanStyle(fontSize = fontSize)) {
            append(staticText1)
        }

        underlineText2?.let { text2 ->
            staticText2?.let { static2 ->
                // 给第二个下划线文本添加标注
                appendAnnotation(tag = "UNDERLINE_TEXT_2", annotation = "click")
                withStyle(
                    style = SpanStyle(
                        textDecoration = TextDecoration.Underline,
                        fontSize = fontSize
                    )
                ) {
                    append(text2)
                }
                appendAnnotation(tag = "UNDERLINE_TEXT_2", annotation = "end")

                // 静态文本2
                withStyle(style = SpanStyle(fontSize = fontSize)) {
                    append(static2)
                }
            }
        }
    }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(start = 15.dp, end = 15.dp, top = 10.dp, bottom = 10.dp)
    ) {
        Card(
            elevation = 0.dp,
            shape = RoundedCornerShape(6.dp),
            border = BorderStroke(2.dp, color = MaterialTheme.colors.grayColor)
        ) {
            Box(
                modifier = Modifier
                    .size(25.dp)
                    .weight(1f)
                    .background(if (isCheck.value) DYTGreenColor else color)
                    .clickable { isCheck.value = !isCheck.value },
                contentAlignment = Alignment.TopStart
            ) {
                if (isCheck.value)
                    Icon(Icons.Default.Check, contentDescription = "", tint = Color.White)
            }
        }

        // 使用ClickableText替代普通Text
        ClickableText(
            modifier = Modifier.padding(start = 10.dp),
            text = annotatedText,
            onClick = { offset ->
                // 检查点击位置是否属于第一个下划线文本
                annotatedText.getStringAnnotations(
                    tag = "UNDERLINE_TEXT_1",
                    start = offset,
                    end = offset
                ).firstOrNull()?.let { onUnderlineText1Click() }
                // 检查点击位置是否属于第二个下划线文本
                annotatedText.getStringAnnotations(
                    tag = "UNDERLINE_TEXT_2",
                    start = offset,
                    end = offset
                ).firstOrNull()?.let { onUnderlineText2Click() }
            }
        )
    }
}

关键说明

  • 用appendAnnotation为每个下划线文本添加专属标记,标记的作用是让ClickableText识别点击区域
  • 替换成ClickableText后,通过getStringAnnotations判断点击位置是否落在某个下划线文本的范围内,从而触发对应的展示逻辑
  • 拆分回调函数后,每个下划线文本的点击逻辑可以独立实现,互不干扰

内容的提问来源于stack exchange,提问作者NewPartizal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:42:54