Cómo habilitar las interacciones del usuario

Jetpack Compose habilita la interactividad detallada en Text. La selección de texto ahora es más flexible y se puede realizar en diseños componibles. Las interacciones de los usuarios en el texto son diferentes de otros diseños componibles, ya que no puedes agregar un modificador a una parte de un elemento Text componible. En esta página, se destacan las APIs que permiten las interacciones del usuario.

Seleccionar texto

De forma predeterminada, no se pueden seleccionar elementos componibles, lo que significa que los usuarios no pueden seleccionar y copiar texto desde tu app. Para habilitar la selección de texto, une tus elementos de texto con un elemento SelectionContainer componible:

@Composable
fun SelectableText() {
    SelectionContainer {
        Text("This text is selectable")
    }
}

Un pasaje de texto breve seleccionado por el usuario

Puede que quieras inhabilitar la selección en partes específicas de un área seleccionable. Para hacerlo, debes unir la parte que no se puede seleccionar con un elemento componible DisableSelection:

@Composable
fun PartiallySelectableText() {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")
        }
    }
}

Un pasaje de texto más largo. El usuario intentó seleccionar todo el fragmento, pero no se resaltaron las dos líneas porque se les aplicó DisableSelection.

Obtener la posición de un clic en el texto

Para escuchar los clics en Text, puedes agregar el modificador clickable. Sin embargo, si deseas obtener la posición de un clic dentro de un elemento Text componible, en caso de que tengas diferentes acciones basadas en distintas partes del texto, debes usar un ClickableText:

@Composable
fun SimpleClickableText() {
    ClickableText(text = AnnotatedString("Click Me"), onClick = { offset ->
        Log.d("ClickableText", "$offset -th character is clicked.")
    })
}

Cómo hacer clic con la anotación

Si un usuario hace clic en un elemento componible Text, tal vez quieras adjuntar información adicional en una parte del valor Text, como una URL adjunta a una palabra específica a fin de abrirla en un navegador. Para hacerlo, debes adjuntar una anotación, que toma una etiqueta (String), un elemento (String) y un rango de texto como parámetros. Desde una AnnotatedString, estas anotaciones se pueden filtrar con sus etiquetas o rangos de texto. Veamos un ejemplo:

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(
            tag = "URL", annotation = "https://developer.android.com"
        )
        withStyle(
            style = SpanStyle(
                color = Color.Blue, fontWeight = FontWeight.Bold
            )
        ) {
            append("here")
        }

        pop()
    }

    ClickableText(text = annotatedText, onClick = { offset ->
        // We check if there is an *URL* annotation attached to the text
        // at the clicked position
        annotatedText.getStringAnnotations(
            tag = "URL", start = offset, end = offset
        ).firstOrNull()?.let { annotation ->
            // If yes, we log its value
            Log.d("Clicked URL", annotation.item)
        }
    })
}