如何在 Jetpack Compose 中使文本可点击?选择一次后还将其切换为不可点击

问题描述 投票:0回答:5

这是我的代码:

Text(
    text = "Resend OTP",
    fontSize = 20.sp,
    color =  Textfieldcolor,
    style = TextStyle(textDecoration = TextDecoration.Underline)
)

我希望文本可以单击一次,然后禁用。

我该怎么做?

kotlin text android-jetpack-compose android-jetpack android-compose-textfield
5个回答
40
投票

您可以将 clickable 修饰符添加到 Text 或使用 ClickableText 而不是 Text

这是如何使用 ClickableText 执行此操作的示例:

var enabled by remember { mutableStateOf(true)}

ClickableText(
    text = AnnotatedString(text) ,
    onClick = {
        if (enabled) {
            enabled = false
            text = "Disabled"
        }
    })

11
投票

就像 @Arpit 提到的,最好使用

TextButton
来实现此目的。 但如果你绝对想使用
Text
,你可以使用以下代码片段。

@Composable 
fun OneTimeClickableText(text : String, onClick : () -> Unit){
    var enabled by rememberSaveable{ mutableStateOf(true)}
    Text(
        modifier = Modifier
            .clickable(enabled = enabled) {
                enabled = false
                onClick()
            },
        text = text
    )
}

也就是说,我这段代码严格适用于一次性可点击文本。我不建议将它用于 OTP 按钮之类的用途;因为用户将无法单击它,除非重新启动您的应用程序。您可以拉出

enabled
变量并从外部对其进行管理(例如,将其禁用一段时间而不是永久)。


5
投票

这是一种以非自定义方式仅使部分文本可点击的方法:

val text = buildAnnotatedString {
    append("This is not clickable ")
    withAnnotation("tag", "annotation") {
        append("This is clickable")
    }
}

ClickableText(text) {
    text.getStringAnnotations(it, it).firstOrNull()?.tag?.let { tag ->
        // Check which tag was clicked
    }
}

1
投票

除了接受的答案可能适合您的大多数情况外,还有其他选项可以满足更多要求:

pointerInput
当您需要长按双击等时

Modifier.pointerInput(Unit) {
                                    detectTapGestures(
                                        onPress = {
                                            println("on press")
                                        },
                                        onTap = {
                                            println("on tap")
                                        },
                                        onDoubleTap = {
                                            println("on double tap")
                                        },
                                        onLongPress = {
                                            println("on long press")
                                        }
                                    )
                                }

如果您需要了解操作,请使用

pointerInteropFilter

.pointerInteropFilter {
                                    when (it.action) {
                                        MotionEvent.ACTION_UP -> {
                                            println("action up")

                                        }

                                        MotionEvent.ACTION_DOWN -> {
                                            println("action Down")

                                        }

                                        else -> {}
                                    }
                                    true
                                } 

当其中一个

onClick
不起作用时请注意。


0
投票

ClicableText
已被弃用

Text()BasicText()

 中使用 
AnnotatedStringLinkAnnotation:

val myAnnotatedString = buildAnnotatedString {
    append("This is ")
    withLink(LinkAnnotation.Url(url = "https://google.com")) {
        append("my link text")
    }
}
Text(text = myAnnotatedString)
更多控制和自定义:
val uriHandler = LocalUriHandler.current
val myAnnotatedString = buildAnnotatedString {
    withLink(
        LinkAnnotation.Url(
            url = "https://google.com",
            styles = TextLinkStyles(
                style = SpanStyle(color = Color.Blue),
                hoveredStyle = SpanStyle(color = Color.Red)
            ),
            linkInteractionListener = {
                // on click...
                uriHandler.openUri("https://google.com")
            }
        )
    ) {
        append("my link text")
    }
}
Text(text = myAnnotatedString)
© www.soinside.com 2019 - 2024. All rights reserved.