我找不到如何使用 Jetpack Compose 链接我的 Text()
。
在撰写之前,我所要做的就是:
Linkify.addLinks(myTextView, Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)
显然,我的 TextView 中包含的所有链接都变成了可点击的链接。
重要提示:Text 的内容来自 API,链接没有固定位置,内容可能包含多个链接。
我想在使用 Jetpack Compose 时保持这种行为,但我找不到任何有关这样做的信息。
有人知道吗?
答案 0 :(得分:2)
您可以使用 AnnotatedString
来实现此行为。
文档:https://developer.android.com/reference/kotlin/androidx/compose/ui/text/AnnotatedString
另外,这个可以帮到你:
答案 1 :(得分:0)
如果有人正在寻找解决方案,以下内容将使您的文本中的任何链接都可点击并设置样式:
@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
)
答案 2 :(得分:0)
我认为现在更好的解决方案是使用 textview 创建自己的组件:
package me.sakuraidev;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class main extends JavaPlugin implements CommandExecutor{
@SuppressWarnings("unused")
private main Plugin;
@Override
public void onEnable(main Plugin) {
this.Plugin = Plugin;
Plugin.getCommand("hello").setExecutor(this);
}
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage("Sorry, only players can run this command");
return true;
}
Player p = (Player) sender;
if(p.hasPermission("hello.use")) {
sender.sendMessage("hi");
} else {
sender.sendMessage("Sorry, but you don't have permission to use this command");
}
return false;
}
}