Jetpack Skomponuj i stylizuj strings.xml

Nov 26 2022
Problem Więc masz wpis w strings.xml z treścią HTML: Cała stylizacja zniknęła! Co się stało? Rozwiązanie Jetpack Compose nie obsługuje jeszcze stylizowanego tekstu.
Logo Jetpack Compose. Wygląda ładnie, ale nie ma stylizowanego tekstu. Dlaczego?

Problem

Masz więc wpis w strings.xml z zawartością 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))
}

Podgląd tekstu. Brakuje stylizacji!

Cała stylizacja zniknęła! Co się stało?

Rozwiązanie

Jetpack Compose nie obsługuje jeszcze stylizowanego tekstu. Ale to proste do naprawienia.

Po numerze 139320238 tworzymy własny program ładujący zasoby łańcuchowe:

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

Podgląd tekstu. Nadal nie ma stylizacji, ponieważ nie jest obsługiwana w wersji zapoznawczej

Ech, co… Nadal NIE STYLIZOWANE? Rzecz w tym, że tryb podglądu również nie obsługuje stylizowanego tekstu.

Ale prawdziwe urządzenie:

Podgląd tekstu na urządzeniu. Stylizacja już jest!

A ponieważ nasi użytkownicy używają tylko prawdziwych urządzeń, wszyscy jesteśmy w porządku.

Pod maską

Komponent Jetpack Compose Text obsługuje stylizowany tekst. Wsparcie nazywa się AnnotatedString. Więc jeśli możemy po prostu dostarczyć tekst z AnnotatedStrings, wszystko jest w porządku.

Od strony Androida zapewnia dwa sposoby uzyskania zlokalizowanego ciągu znaków:

  • String getString(id), który zwraca ciąg znaków. To nie może zawierać żadnych stylów, a tagi HTML są po prostu odrzucane i ignorowane.
  • CharSequence getText(id), która zwraca CharSequence. Chwyt polega na tym, że ta sekwencja zawiera również rozpiętości stylów zdefiniowane w HTML.