【问题标题】:AutoLink for Android Compose Text适用于 Android 的 AutoLink 撰写文本
【发布时间】:2021-02-20 15:28:19
【问题描述】:

有什么方法可以在 JetPack Compose Text 上使用 android:autoLink 功能?

我知道,在一个简单的标签/修饰符中使用此功能可能不是“声明方式”,但也许有一些简单的方法?

对于文本样式我可以使用这种方式

 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())

但是,我如何在此处管理点击次数?如果我以编程方式说出我对系统的期望行为(电子邮件、电话、网络等),那就太好了。喜欢它。与 TextView 一起使用。 谢谢

【问题讨论】:

  • 如果您希望看到 Compose 直接支持此功能,我在 Jetpack Compose 问题跟踪器上打开了一个功能请求 - issuetracker.google.com/issues/205183601
  • 你得到正确的解决方案了吗?

标签: android textview android-jetpack-compose


【解决方案1】:

我们可以像下面这个例子一样在Android Compose中实现LinkifyTextView

@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,我们可以打开电子邮件、电话或网络等链接。

参考:https://www.hellsoft.se/rendering-markdown-with-jetpack-compose/

【讨论】:

  • 感谢您的解决方案,它适用于 URL。但它不适用于电子邮件和电话。但是对于这些情况,我们可以使用 deepLink,例如 mailto:example@email.com 所以,是的!谢谢! :)
  • 更多最新解决方案在这里stackoverflow.com/a/65656351/2633359
【解决方案2】:

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://stackoverflow.com/ works fine"
 )

【讨论】:

    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    相关资源
    最近更新 更多