Android(Kotlin)

Jetpack Compose의 BasicTextField에 스타일 적용하기

E.I.T.U 2023. 11. 2. 16:54

카카오톡의 @호출 기능처럼 텍스트 입력창에 스타일을 적용해야할 일이 생겼다.

Text()의 경우에는 AnnotatedString을 통해 원하는 스타일을 적용할 수 있었지만

BasicTextField의 경우 TextFieldValue를 사용하기 때문에 어떻게 해야할지 막막했는데

VisualTransformation을 통해 스타일을 적용할 수 있다는 것을 알았다.

 

TextField에서 VisualTransformation은 실제 value에 적용되는것이 아닌

말 그대로 보이는 text를 변경하는 속성으로써

보통 비밀번호 입력창에서 PasswordVisualTransformation을 적용하는 경우 등에 사용한다.

 

inner class AnnotatedStringVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {

        val annotated = buildAnnotatedStringWithIdColor(text.toString())

        val offsetMapping = MyOffsetMapping()

        return TransformedText(
            text = annotated,
            offsetMapping = offsetMapping
        )
    }

    private fun buildAnnotatedStringWithIdColor(text : String) : AnnotatedString {
        // splits by whitespace
        val words: List<String> = text.split("\\s+".toRegex())

        val builder = AnnotatedString.Builder()
        for ((count, word) in words.withIndex()) {
            builder.withStyle(
                style = SpanStyle(
                    if (word.startsWith("@")) {
                        Color.Green
                    }
                    else {
                        Color.Black
                    }

                )
            ) {
            	if (count == words.size) append("$word")
                else append("$word ")
            }
        }
        return builder.toAnnotatedString()
    }
}

 

커스텀 VisualTransformation을 통해 원하는 스타일을 적용한 AnnotatedString을 생성하고

TransformedText의 인수로써 넘겨주면 된다.

 

참고로 offsetMapping은 커서의 위치를 나타낼 때 사용한다.