Android 的自动链接撰写文本
AutoLink for Android Compose Text
有没有办法在 JetPack Compose Text 上使用 android:autoLink 功能?
我知道,在一个简单的 tag/modifier 中使用此功能可能不是“声明方式”,但也许有一些简单的方法?
对于样式文本,我可以使用这种方式
val apiString = AnnotatedString.Builder("API provided by")
apiString.pushStyle(
style = SpanStyle(
color = Color.Companion.Blue,
textDecoration = TextDecoration.Underline
)
)
apiString.append("https://example.com")
Text(text = apiString.toAnnotatedString())
但是,我如何管理此处的点击次数?如果我以编程方式说出我对系统的期望行为(电子邮件、phone、网络等),那就太好了。喜欢它。与 TextView 一起工作。
谢谢
我们可以在 Android Compose 中实现 Linkify 种 TextView
,如下面的示例,
@Composable
fun LinkifySample() {
val uriHandler = UriHandlerAmbient.current
val layoutResult = remember {
mutableStateOf<TextLayoutResult?>(null)
}
val text = "API provided by"
val annotatedString = annotatedString {
pushStyle(
style = SpanStyle(
color = Color.Companion.Blue,
textDecoration = TextDecoration.Underline
)
)
append(text)
addStringAnnotation(
tag = "URL",
annotation = "https://example.com",
start = 0,
end = text.length
)
}
Text(
fontSize = 16.sp,
text = annotatedString, modifier = Modifier.tapGestureFilter { 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 }
)
}
在上面的例子中,我们可以看到我们给出了文本,我们还使用了addStringAnnotation
来设置标签。并使用tapGestureFilter
,我们可以得到点击的注释。
最后使用 UriHandlerAmbient.current
我们可以打开 link 电子邮件,phone 或网页。
参考:https://www.hellsoft.se/rendering-markdown-with-jetpack-compose/
jetpack compose 最重要的部分是与原生 android 组件的兼容性。
创建一个使用 TextView 的组件并使用它:
@Composable
fun DefaultLinkifyText(modifier: Modifier = Modifier, text: String?) {
val context = LocalContext.current
val customLinkifyTextView = remember {
TextView(context)
}
AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView ->
textView.text = text ?: ""
LinkifyCompat.addLinks(textView, Linkify.ALL)
Linkify.addLinks(textView, Patterns.PHONE,"tel:",
Linkify.sPhoneNumberMatchFilter, Linkify.sPhoneNumberTransformFilter)
textView.movementMethod = LinkMovementMethod.getInstance()
}
}
使用方法:
DefaultLinkifyText(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
text = "6999999 and https://whosebug.com/ works fine"
)
有没有办法在 JetPack Compose Text 上使用 android:autoLink 功能?
我知道,在一个简单的 tag/modifier 中使用此功能可能不是“声明方式”,但也许有一些简单的方法?
对于样式文本,我可以使用这种方式
val apiString = AnnotatedString.Builder("API provided by")
apiString.pushStyle(
style = SpanStyle(
color = Color.Companion.Blue,
textDecoration = TextDecoration.Underline
)
)
apiString.append("https://example.com")
Text(text = apiString.toAnnotatedString())
但是,我如何管理此处的点击次数?如果我以编程方式说出我对系统的期望行为(电子邮件、phone、网络等),那就太好了。喜欢它。与 TextView 一起工作。 谢谢
我们可以在 Android Compose 中实现 Linkify 种 TextView
,如下面的示例,
@Composable
fun LinkifySample() {
val uriHandler = UriHandlerAmbient.current
val layoutResult = remember {
mutableStateOf<TextLayoutResult?>(null)
}
val text = "API provided by"
val annotatedString = annotatedString {
pushStyle(
style = SpanStyle(
color = Color.Companion.Blue,
textDecoration = TextDecoration.Underline
)
)
append(text)
addStringAnnotation(
tag = "URL",
annotation = "https://example.com",
start = 0,
end = text.length
)
}
Text(
fontSize = 16.sp,
text = annotatedString, modifier = Modifier.tapGestureFilter { 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 }
)
}
在上面的例子中,我们可以看到我们给出了文本,我们还使用了addStringAnnotation
来设置标签。并使用tapGestureFilter
,我们可以得到点击的注释。
最后使用 UriHandlerAmbient.current
我们可以打开 link 电子邮件,phone 或网页。
参考:https://www.hellsoft.se/rendering-markdown-with-jetpack-compose/
jetpack compose 最重要的部分是与原生 android 组件的兼容性。
创建一个使用 TextView 的组件并使用它:
@Composable
fun DefaultLinkifyText(modifier: Modifier = Modifier, text: String?) {
val context = LocalContext.current
val customLinkifyTextView = remember {
TextView(context)
}
AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView ->
textView.text = text ?: ""
LinkifyCompat.addLinks(textView, Linkify.ALL)
Linkify.addLinks(textView, Patterns.PHONE,"tel:",
Linkify.sPhoneNumberMatchFilter, Linkify.sPhoneNumberTransformFilter)
textView.movementMethod = LinkMovementMethod.getInstance()
}
}
使用方法:
DefaultLinkifyText(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight(),
text = "6999999 and https://whosebug.com/ works fine"
)