Android compose实现SpannableString效果

607 阅读1分钟

首先贴一下官网的教程: developer.android.com/jetpack/com… 很详细可以看一下,这里主要写一下遇到的点击的坑:

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(tag = "URL",
                             annotation = "https://developer.android.com")
        withStyle(style = SpanStyle(color = Color.Blue,
                                    fontWeight = FontWeight.Bold)) {
            append("here")
        }

        pop()
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            // We check if there is an *URL* annotation attached to the text
            // at the clicked position
            annotatedText.getStringAnnotations(tag = "URL", start = offset,
                                                    end = offset)
                .firstOrNull()?.let { annotation ->
                    // If yes, we log its value
                    Log.d("Clicked URL", annotation.item)
                }
        }
    )
}

这里我主要需要实现此效果

image.png 服务协议单独一个url 隐私政策单独一个 同时和字不能有点击效果 然而官网的并不能实现(可能我的理解有问题) 踩过很多坑后得出结论 直接上代码

@Composable
private fun annotatedString() = buildAnnotatedString {
    withStyle(style = SpanStyle(color = colorResource(id = R.color.color00D8D3))) {
        pushStringAnnotation(
            tag = "URL", annotation = "https://developer.android.com"
        )
        append("《服务协议》")
        pop()
    }

    withStyle(style = SpanStyle(color = colorResource(id = R.color.color9FA1AA))) {
        append("和")
    }

    withStyle(style = SpanStyle(color = colorResource(id = R.color.color00D8D3))) {
        pushStringAnnotation(
            tag = "URL", annotation = "https://baidu.com"
        )
        append("《隐私政策》")
        pop()
    }
}

```
val annotatedText = annotatedString()
ClickableText(text = annotatedText, onClick = { offset ->
    annotatedText.getStringAnnotations(tag = "URL", start = offset, end = offset).firstOrNull()?.let {
        ToastUtils.showShort("去${it.item}")
    }
})
```

url通过it.item获取即可 记得加入pop()