Jetpack Compose dan menata strings.xml

Nov 26 2022
Masalah Jadi, Anda memiliki entri di strings.xml dengan konten HTML: Semua penataan gaya hilang! Apa yang terjadi? Solusi Jetpack Compose belum mendukung teks bergaya.
Logo Jetpack Compose. Terlihat bagus, tetapi tidak memiliki teks bergaya. Mengapa demikian?

Masalah

Jadi, Anda memiliki entri di strings.xml dengan konten HTML:

<string name="neatly_styled">Nice <u>underlined</u> and <b>bold</b> text.</string>

@Preview
@Compose
fun PreviewStyledText() {
  Text(text = stringResource(R.string.neatly_styled))
}

Pratinjau teks. Styling hilang!

Semua gaya hilang! Apa yang terjadi?

Larutan

Jetpack Compose belum mendukung teks bergaya. Tapi mudah untuk memperbaikinya.

Setelah masalah 139320238 , kami membuat pemuat sumber daya string kami sendiri:

@Composable
fun annotatedStringResource(@StringRes id: Int): AnnotatedString {
    val resources = LocalContext.current.resources
    return remember(id) {
        val text = resources.getText(id)
        if (text is Spanned) {
            val spanStyles = mutableListOf<AnnotatedString.Range<SpanStyle>>()
            spanStyles.addAll(text.getSpans(0, text.length, UnderlineSpan::class.java).map {
                AnnotatedString.Range(
                    SpanStyle(textDecoration = TextDecoration.Underline),
                    text.getSpanStart(it),
                    text.getSpanEnd(it)
                )
            })
            spanStyles.addAll(text.getSpans(0, text.length, StyleSpan::class.java).map {
                AnnotatedString.Range(
                    SpanStyle(fontWeight = FontWeight.Bold),
                    text.getSpanStart(it),
                    text.getSpanEnd(it)
                )
            })
            AnnotatedString(text.toString(), spanStyles = spanStyles)
        } else {
            AnnotatedString(text.toString())
        }
    }
}

@Preview
@Composable
fun PreviewStyledTextFix() {
    Text(text = annotatedStringResource(R.string.styled_text))
}

Pratinjau teks. Tetap tanpa gaya, karena tidak didukung di Pratinjau

Eh apa… Masih BELUM GAYA? Masalahnya, mode Pratinjau juga tidak mendukung teks bergaya.

Tapi, perangkat nyata tidak:

Pratinjau teks di perangkat. Gaya ada di sana!

Dan karena pengguna kami hanya menggunakan perangkat nyata, kami semua baik-baik saja.

Dibawah tenda

Komponen Jetpack Compose Text mendukung teks bergaya. Dukungan ini disebut AnnotatedString. Jadi jika kita bisa menyediakan Teks dengan AnnotatedStrings, kita semua baik-baik saja.

Dari sisi Android, ini menyediakan dua cara untuk mendapatkan string yang dilokalkan:

  • String getString(id), yang mengembalikan sebuah String. Itu tidak boleh berisi gaya apa pun dan tag HTML dibuang begitu saja dan diabaikan.
  • CharSequence getText(id), yang mengembalikan CharSequence. Menariknya, urutan ini juga berisi rentang gaya yang ditentukan dalam HTML.