用撰写文本链接 [英] Linkify with Compose Text

查看:104
本文介绍了用撰写文本链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到使用Jetpack Compose链接我的 Text()的方法.

I can't find how to linkify my Text() using Jetpack Compose.

在撰写之前,我要做的只是:

Before compose all I had to do was:

Linkify.addLinks(myTextView,Linkify.EMAIL_ADDRESSES或Linkify.WEB_URLS)

很显然,我的TextView中包含的所有链接都变成了可点击的链接.

And all the links contained in my TextView were becoming clickable links, obviously.

重要提示:文本的内容来自API,链接没有固定的位置,内容可能包含多个链接.

Important: The content of the Text is coming from an API and the links do not have a fixed position and content may contain multiple links.

我想通过使用Jetpack Compose保持这种行为,但是我找不到有关此操作的任何信息.

I want to keep this behavior with using Jetpack Compose but I can't find any information about doing that.

有人知道吗?

推荐答案

如果有人正在寻找解决方案,则以下内容将使任何链接都可单击并在您的文本中设置样式:

In case someone is looking for a solution, the following will make any links clickable and styled in your text:

@Composable
fun LinkifyText(text: String, modifier: Modifier = Modifier) {
    val uriHandler = LocalUriHandler.current
    val layoutResult = remember {
        mutableStateOf<TextLayoutResult?>(null)
    }
    val linksList = extractUrls(text)
    val annotatedString = buildAnnotatedString {
        append(text)
        linksList.forEach {
            addStyle(
                    style = SpanStyle(
                            color = Color.Companion.Blue,
                            textDecoration = TextDecoration.Underline
                    ),
                    start = it.start,
                    end = it.end
            )
            addStringAnnotation(
                    tag = "URL",
                    annotation = it.url,
                    start = it.start,
                    end = it.end
            )
        }
    }
    Text(text = annotatedString, style = MaterialTheme.typography.body1, modifier = modifier.pointerInput(Unit) {
    detectTapGestures { offsetPosition ->
        layoutResult.value?.let {
            val position = it.getOffsetForPosition(offsetPosition)
            annotatedString.getStringAnnotations(position, position).firstOrNull()
                ?.let { result ->
                    if (result.tag == "URL") {
                        uriHandler.openUri(result.item)
                    }
                }
        }
    }
},
            onTextLayout = { layoutResult.value = it }
    )
}

private val urlPattern: Pattern = Pattern.compile(
        "(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
                + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
                + "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
        Pattern.CASE_INSENSITIVE or Pattern.MULTILINE or Pattern.DOTALL
)

fun extractUrls(text: String): List<LinkInfos> {
    val matcher = urlPattern.matcher(text)
    var matchStart: Int
    var matchEnd: Int
    val links = arrayListOf<LinkInfos>()

    while (matcher.find()) {
        matchStart = matcher.start(1)
        matchEnd = matcher.end()

        var url = text.substring(matchStart, matchEnd)
        if (!url.startsWith("http://") && !url.startsWith("https://"))
            url = "https://$url"

        links.add(LinkInfos(url, matchStart, matchEnd))
    }
    return links
}

data class LinkInfos(
        val url: String,
        val start: Int,
        val end: Int
)

这篇关于用撰写文本链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆