Search code examples
androidtextviewandroid-jetpack-compose

AutoLink for Android Compose Text


Is there any way to use android:autoLink feature on JetPack Compose Text?

I know, that it is maybe not "declarative way" for using this feature in one simple tag/modifier, but maybe there is some easy way for this?

For styling text I can use this way

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

But, how can I manage clicks here? And would be great, if I programatically say what behaviour I expect from the system (email, phone, web, etc). Like it. works with TextView. Thank you


Solution

  • We can achieve Linkify kind of TextView in Android Compose like this example below,

    @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 }
        )
    }
    

    In the above example, we can see we give the text and also we use addStringAnnotation to set the tag. And using tapGestureFilter, we can get the clicked annotation.

    Finally using UriHandlerAmbient.current we can open the link like email, phone, or web.

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