사용자 상호작용 사용 설정

Jetpack Compose는 Text에서 세분화된 상호작용을 사용 설정합니다. 이제 여러 컴포저블 레이아웃에서 더 유연하게 텍스트를 선택할 수 있습니다. Text 컴포저블의 부분에 수정자를 추가할 수 없으므로 텍스트의 사용자 상호작용은 다른 컴포저블 레이아웃과 다릅니다. 이 페이지에서는 사용자 상호작용을 사용 설정하는 API를 중점적으로 설명합니다.

텍스트 선택

기본적으로 컴포저블은 선택할 수 없습니다. 즉, 사용자가 앱에서 텍스트를 선택하고 복사할 수 없습니다. 텍스트 선택을 사용 설정하려면 텍스트 요소를 SelectionContainer 컴포저블로 래핑합니다.

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

사용자가 선택한 짧은 텍스트 문구

선택 가능한 영역의 특정 부분에서 선택 기능을 사용 중지해야 하는 경우도 있습니다. 이렇게 하려면 선택 불가능한 부분을 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")
        }
    }
}

긴 텍스트 문구 사용자가 문구 전체를 선택하려고 했지만 두 줄에 DisableSelection이 적용되어 선택되지 않았습니다.

텍스트에서 클릭 위치 가져오기

Text의 클릭을 수신하려면 clickable 수정자를 추가하면 됩니다. 그러나 Text 컴포저블 내에서 클릭 위치를 가져오려면 텍스트의 부분에 따라 작업이 다른 경우 ClickableText를 대신 사용해야 합니다.

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

주석이 추가된 클릭

사용자가 Text 컴포저블을 클릭할 때 예를 들어 브라우저에서 열리는 특정 단어에 연결된 URL과 같이 Text 값의 부분에 정보를 추가해야 하는 경우도 있습니다. 이렇게 하려면 태그(String), 항목(String), 텍스트 범위를 매개변수로 사용하는 주석을 추가해야 합니다. AnnotatedString에서 이러한 주석을 태그 또는 텍스트 범위로 필터링할 수 있습니다. 예를 들면 다음과 같습니다.

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