Jetpack 编写文本 超链接文本的某些部分

news/2024/12/19 15:02:35/文章来源:https://www.cnblogs.com/johnsena/p/18617275

如何将超链接添加到文本组件文本的某个部分?

我可以将链接部分设置为蓝色并带有下划线,如下图所示,但我如何将该部分也转换为链接?buildAnnotatedString

在此处输入图像描述

val annotatedLinkString = buildAnnotatedString {
val str = "Click this link to go to web site"
val startIndex = str.indexOf("link")
val endIndex = startIndex + 4
append(str)
addStyle(
style = SpanStyle(
color = Color(0xff64B5F6),
textDecoration = TextDecoration.Underline
), start = startIndex, end = endIndex
)
}

Text(modifier = modifier.padding(16.dp).fillMaxWidth(),text = annotatedLinkString
)

我也可以得到,但有什么办法可以使用它吗?SpannedText

val str: Spanned = HtmlCompat.fromHtml(
"<a href="http://www.github.com">Github", HtmlCompat.FROM_HTML_MODE_LEGACY
)
人造人android-jetpack-compose 中android-jetpack-撰写文本
共享
改进此问题
跟随
编辑于 2021 年 2 月 15 日 13:01
问 Jan 4, 2021 在 17:52
色雷斯的用户头像
色雷斯语
64,9 千米2020 枚金徽章206206 枚银质徽章372372 枚铜牌
1
另请考虑触摸目标的大小:slack-chats.kotlinlang.org/t/2651976

乌利
评论11月 2, 2022 在 10:55
添加评论
22 回答
排序依据:

最高分 (默认)
124

标记的答案让新手感到困惑,我举一个完整的例子

请不要忘记以pushStringAnnotation pop()

val annotatedString = buildAnnotatedString {
append("By joining, you agree to the ")

pushStringAnnotation(tag = "policy", annotation = "https://google.com/policy")
withStyle(style = SpanStyle(color = MaterialTheme.colors.primary)) {append("privacy policy")
}
pop()append(" and ")pushStringAnnotation(tag = "terms", annotation = "https://google.com/terms")withStyle(style = SpanStyle(color = MaterialTheme.colors.primary)) {append("terms of use")
}pop()

}

ClickableText(text = annotatedString, style = MaterialTheme.typography.body1, onClick = { offset ->
annotatedString.getStringAnnotations(tag = "policy", start = offset, end = offset).firstOrNull()?.let {
Log.d("policy URL", it.item)
}

annotatedString.getStringAnnotations(tag = "terms", start = offset, end = offset).firstOrNull()?.let {Log.d("terms URL", it.item)
}

})

最终效果

在此处输入图像描述

如果您需要 #tags 和@mentions请参考我的其他答案

在此处输入图像描述

共享
改进此答案
跟随
编辑于 6月 28 日 13:44
miken32 的用户头像
米肯32
42,7 千米1616 枚金质徽章121121 枚银质徽章171171 枚铜牌
已回答 2021年10月13日 星期五 4:54
Gaohomway 的用户头像
高鸿威
4,00055 枚金徽章3232 枚银质徽章5050 枚铜牌
4
好!您只是忘记在第一个 pushStringAnnotation 和 withStyle 方法对之后调用 pop()。

Zdenek Sima
评论12月 17, 2021 在 9:56
2
有没有办法为这样的视图添加一些选定的状态/涟漪效果?现在它看起来完全是静态的

科斯蒂亚·鲁坚科
评论1月 27, 2022 在 12:24
3
什么是 Pop()?为什么我们在这里需要这个?

迈克尔·阿比佐夫
评论9月 9, 2022 在 11:36
这很接近,但我认为当你将鼠标悬停在超链接上时,它们通常会改变鼠标光标,而 ClickableText 似乎并没有立即做到这一点。😦

博内
评论3月 17 在 11:56
3
当然,ClickableText 现在已经被弃用了,谁能给我举一个例子来说明我们现在应该如何做到这一点?

项目Delta
评论6月 20 在 13:50
添加评论
79

withLink
ClickableText已弃用,用于创建 .withLinkAnnotatedString

@Preview
@Composable
fun LinkAnnotationTest() {
val annotatedLinkString: AnnotatedString = remember {
buildAnnotatedString {

        val style = SpanStyle(color = Color.Black,fontSize = 18.sp,)val styleCenter = SpanStyle(color = Color(0xff64B5F6),fontSize = 20.sp,textDecoration = TextDecoration.Underline)withStyle(style = style) {append("Click this ")}withLink(LinkAnnotation.Url(url = "https://github.com")) {withStyle(style = styleCenter) {append("link")}}withStyle(style = style) {append(" to go to website")}}
}Column(modifier = Modifier.padding(16.dp)
) {Text(annotatedLinkString)
}

}
ClickableText(已弃用)
您可以使用 which 返回文本的位置,并在浏览器中打开 URI。ClickableTextUriHandler

val annotatedLinkString: AnnotatedString = buildAnnotatedString {

val str = "Click this link to go to web site"
val startIndex = str.indexOf("link")
val endIndex = startIndex + 4
append(str)
addStyle(style = SpanStyle(color = Color(0xff64B5F6),fontSize = 18.sp,textDecoration = TextDecoration.Underline), start = startIndex, end = endIndex
)// attach a string annotation that stores a URL to the text "link"
addStringAnnotation(tag = "URL",annotation = "https://github.com",start = startIndex,end = endIndex
)

}

// UriHandler parse and opens URI inside AnnotatedString Item in Browse
val uriHandler = LocalUriHandler.current

// 🔥 Clickable text returns position of text that is clicked in onClick callback
ClickableText(
modifier = modifier
.padding(16.dp)
.fillMaxWidth(),
text = annotatedLinkString,
onClick = {
annotatedLinkString
.getStringAnnotations("URL", it, it)
.firstOrNull()?.let { stringAnnotation ->
uriHandler.openUri(stringAnnotation.item)
}
}
)
共享
改进此答案
跟随
编辑于 11月 8 日 11:47
答案 2021年1月10日 (星期日) 17:36
色雷斯的用户头像
色雷斯语
64,9 千米2020 枚金徽章206206 枚银质徽章372372 枚铜牌
7
我如何使用字符串资源进行这项工作,似乎是硬编码字符串的好方法。

Guanaco 开发
评论10月 7, 2021 在 20:24
1
@GuanacoDevs在下面查看我的答案!

Chantell Osejo
评论5月 24, 2022 在 21:50
@ChantellOsejo 这似乎是一条路要走,你可能会获得更多的控制权。然而,这个答案为我带来了一种更简化的方法。

Guanaco 开发
评论5月 26, 2022 在 23:20
很好的回答。我只想指出,如果你只需要在应用中运行一个函数(比如移动到另一个 fragment),你可以省略 addStringAnnotation,直接从 ClickableText 构造函数中的 onClick 方法调用该函数。

Android开发
评论11月 22, 2022 在 19:52
1
请记住,UriHandler 并不关心 ActivityNotFoundException(用户没有浏览器)。

丹尼尔·帕夫连科
评论12月 4, 2023 在 7:04
显示 5 更多评论
24

对于任何寻找可重用复制粘贴解决方案的人,

创建一个新文件并复制粘贴此代码,LinkText.kt

data class LinkTextData(
val text: String,
val tag: String? = null,
val annotation: String? = null,
val onClick: ((str: AnnotatedString.Range) -> Unit)? = null,
)

@Composable
fun LinkText(
linkTextData: List,
modifier: Modifier = Modifier,
) {
val annotatedString = createAnnotatedString(linkTextData)

ClickableText(text = annotatedString,style = MaterialTheme.typography.body1,onClick = { offset ->linkTextData.forEach { annotatedStringData ->if (annotatedStringData.tag != null && annotatedStringData.annotation != null) {annotatedString.getStringAnnotations(tag = annotatedStringData.tag,start = offset,end = offset,).firstOrNull()?.let {annotatedStringData.onClick?.invoke(it)}}}},modifier = modifier,
)

}

@Composable
private fun createAnnotatedString(data: List): AnnotatedString {
return buildAnnotatedString {
data.forEach { linkTextData ->
if (linkTextData.tag != null && linkTextData.annotation != null) {
pushStringAnnotation(
tag = linkTextData.tag,
annotation = linkTextData.annotation,
)
withStyle(
style = SpanStyle(
color = MaterialTheme.colors.primary,
textDecoration = TextDecoration.Underline,
),
) {
append(linkTextData.text)
}
pop()
} else {
append(linkTextData.text)
}
}
}
}
用法

LinkText(
linkTextData = listOf(
LinkTextData(
text = "Icons made by ",
),
LinkTextData(
text = "smalllikeart",
tag = "icon_1_author",
annotation = "https://www.flaticon.com/authors/smalllikeart",
onClick = {
Log.d("Link text", "${it.tag} ${it.item}")
},
),
LinkTextData(
text = " from ",
),
LinkTextData(
text = "Flaticon",
tag = "icon_1_source",
annotation = "https://www.flaticon.com/",
onClick = {
Log.d("Link text", "${it.tag} ${it.item}")
},
)
),
modifier = Modifier
.padding(
all = 16.dp,
),
)
Screenshot,

Screenshot

Note

I am handling web pages manually using a composable. Use or other alternatives if manual control is not required.UriHandler
Style clickable and other text as required in .LinkText

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/855406.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修改网站统计图标的位置,网站统计图标位置调整指南

修改网站统计图标的位置通常涉及编辑网站的HTML和CSS文件。以下是详细的步骤:确定修改需求:明确需要将统计图标移动到的具体位置。备份网站文件:在进行任何修改之前,建议先备份网站的所有文件。连接到FTP服务器:使用FTP客户端(如FileZilla、WinSCP等)连接到你的服务器。…

C语言浮点数相等判定

等价关系 按照离散数学的等价关系叙述,集合 \(X\) 上的关系 \(R \subset (X, X)\) 如果满足反身性: \((x, x) \in R, \forall x \in X\),自己等于自己 对称性: 如果 \((x, y) \in R\),则 \((y, x) \in R\),我等于你,则你也等于我 传递性: 如果 \((x, y) \in R\) 且 \((y, …

怎么修改网站admin密码,如何安全地修改网站后台管理系统的admin密码,提升安全性,防止未授权访问

修改网站后台管理系统的admin密码是确保网站安全的重要措施。以下是详细的修改步骤:登录后台管理系统:使用当前的admin账户登录网站后台管理系统。 确保使用的是最新的浏览器,以获得最佳的用户体验。进入用户管理页面:在后台管理系统中,找到“用户管理”或“管理员管理”选…

PbootCMS 织梦支付宝接口常见错误

错误代码 ILLEGAL_PARTNER:更新 PARTNER 值和安全校检码。 确认 PARTNER 值和安全校检码对应且有效。 确认 PARTNER 开通了所需的服务。错误代码 HAS_NO_PRIVILEGE:登录签约的支付宝账号,查询接口服务类型和合同生效时间。 确认服务名称、合同生效时间、合作者身份ID和校验码…

帝国CMS调用标题分类灵动标签

[e:loop={1,5,0,0}] 【<a href="<?=sys_ReturnBqInfoTypeUrl($bqr[ttid])?>"><?=class_tr[$bqr[ttid]][tname]?></a>】 <a href="<?=$bqsr[titleurl]?>" target="_blank"><?=$bqr[title]?>&l…

旅游开发团队协作,什么办公软件能增进默契?

冬季旅游市场具有独特的魅力与挑战,对于旅游公司而言,选择合适的团队协作办公软件至关重要。这些软件不仅要满足日常业务需求,更要契合冬季旅游的特殊情境,如应对旅游高峰期的高效协作、保障寒冷天气下旅游行程的顺利进行等。对于 MBTI 中的 J 人来说,有序、高效且可视化的…

SpringCodel微服务

SpringCodel微服务 docker启动命令: systemctl start docker 启动docker systemctl status docker 查看docker状态 systemctl enable docker 设置开机自启设置容器开机自启 docker update status=aways 容器名docker ps 格式化输出容器内容 (1)--format &qu…

验证云通行证失败, 请求连接无效

新合新公有云登录协同开发平台登录时提示"验证云通行证失败, 请求连接无效", 其他私有环境都正常 解决方案: 需要通过金蝶引导程序更新一下BOS程序

给我2分钟,保证教会你在Vue3中实现一个定高的虚拟列表

前言 虚拟列表对于大部分一线开发同学来说是一点都不陌生的东西了,有的同学是直接使用第三方组件。但是面试时如果你简历上面写了虚拟列表,却给面试官说是通过三方组件实现的,此时空气可能都凝固了。所以这篇文章欧阳将会教你2分钟内实现一个定高的虚拟列表,至于不定高的虚…

盘点2024年10款最热门LLM网关/AI网关

随着人工智能技术的飞速发展,将大型语言模型(LLM)部署到生产环节变得日益复杂。特别是在AI和基于LLM的API需求激增的当下,这一挑战尤为突出。Gartner的预测显示,到2026年,由AI和LLM工具驱动的API需求将激增超过30%,这无疑强调了高效模型管理的重要性。 在这方面,企业面…

第四天案例练习-banner效果

Banner设计:是一种用于展示品牌、产品或服务信息的网络广告设计。 通常以横幅的形式出现在网页或移动端屏幕的顶部,也可以在社交媒体平台上使用<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name=&q…

从5天到1天,某大型国有集团的数智化转型经历了什么?

“只有决策快、公司运营快之后,公司才能实现降本增效”。 从北京到新疆、从中国到南非,从奥运会场馆的水泥混凝土到钱塘江畔拔地而起的高楼房产,无不存在着某大型国有集团的身影。 历经60多年沧桑巨变,该集团已发展成为以“新型绿色环保建材制造、贸易及服务,房地产开发经…