Jetpack Composer et styliser strings.xml
Problème
Vous avez donc une entrée dans strings.xml avec du contenu 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))
}
Tout le style est parti! Qu'est-il arrivé?
La solution
Jetpack Compose ne prend pas encore en charge le texte stylisé. Mais c'est simple à réparer.
Suite au problème 139320238 , nous créons notre propre chargeur de ressources de chaîne :
@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 quoi… Toujours PAS DE STYLE ? Le fait est que le mode Aperçu ne prend pas non plus en charge le texte stylé.
Mais, un vrai appareil fait :
Et parce que nos utilisateurs n'utilisent que de vrais appareils, nous allons tous bien.
Sous la capuche
Le composant Jetpack Compose Text prend en charge le texte stylisé. Le support est appelé AnnotatedString. Donc, si nous pouvons simplement fournir du texte avec AnnotatedStrings, tout va bien.
Du côté Android, il propose deux façons d'obtenir une chaîne localisée :
- String getString(id), qui renvoie une chaîne. Cela ne peut contenir aucun style et les balises HTML sont simplement supprimées et ignorées.
- CharSequence getText(id), qui renvoie un CharSequence. Le hic, c'est que cette séquence contient également les étendues de style définies en HTML.