Jetpack Compose e stilizza strings.xml
Problema
Quindi hai una voce in strings.xml con contenuto 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))
}
Tutto lo stile è sparito! Cosa è successo?
Soluzione
Jetpack Compose non supporta ancora il testo con stile. Ma è semplice da risolvere.
A seguito del problema 139320238 , creiamo il nostro caricatore di risorse di stringa:
@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))
}
Eh cosa... Ancora NON IN STILE? Il fatto è che la modalità Anteprima non supporta neanche il testo in stile.
Ma un vero dispositivo fa:
E poiché i nostri utenti utilizzano solo dispositivi reali, stiamo tutti bene.
Sotto il cappuccio
Il componente Jetpack Compose Text supporta il testo con stile. Il supporto si chiama AnnotatedString. Quindi, se possiamo solo fornire Text con AnnotatedStrings, stiamo tutti bene.
Dal lato Android, fornisce due modi per ottenere una stringa localizzata:
- String getString(id), che restituisce una stringa. Questo non può contenere alcuno stile e i tag HTML vengono semplicemente eliminati e ignorati.
- CharSequence getText(id), che restituisce una CharSequence. Il problema è che questa sequenza contiene anche gli intervalli di stile definiti in HTML.