Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiplatform Compose state does not update font change in Text on Android (on IOS it works well)

we are working on some kind of reader experience for the users. We are trying to allow the user to change font size, color, etc. One of the options is to change the font completely.

What we faced, is that it does not work on Android (well maybe kind of does), but works well on iOS. The whole example project can be found here -> https://github.com/fandomWojtek/Test_ReaderApp

We use Compose Multiplatform 1.6.10, Kotlin 2.0.0, Compose Resources

And now to the point -> we have a mutable state of Text Style

    data class Style(val color: Color = Color.Black, val fontSize: Float = 14f, val fontFamily: FontResource = Res.font.rubik_regular)
    
    
    @Composable
    fun TestScreen() {
        var styleState by remember {
            mutableStateOf(Style())
        }
        Column(modifier = Modifier.background(Color.White)) {
            LazyColumn(modifier = Modifier.weight(1.0f), verticalArrangement = Arrangement.spacedBy(24.dp)) {
                for (i in 0..100) {
                    item {
                        Text(
                            staticText,
                            style = style.copy(color = styleState.color, fontSize = styleState.fontSize.sp, fontFamily = FontFamily(Font(styleState.fontFamily, FontWeight.Normal)))
                            )
                    }
                }
            }
           //Some code removed to readability
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
                Text(
                    modifier = Modifier.padding(16.dp).clickable {
                        styleState = (styleState.copy(fontFamily = Res.font.rubik_regular))
                    },
                    text = "roboto",
                    style = style
                )
    
                Text(
                    modifier = Modifier.padding(16.dp).clickable {
                        styleState = (styleState.copy(fontFamily = Res.font.HelveticaNeueMedium))
                    },
                    text = "helvetica",
                    style = style
                )
    
                Text(
                    modifier = Modifier.padding(16.dp).clickable {
                        styleState = (styleState.copy(fontFamily = Res.font.COMICSANS))
                    },
                    text = "Comic Sans",
                    style = style
                )
            }
        }
    }

And to our surprise, it does not work on Android, the Text is doing a recomposition, but it does not update on the screen (when you scroll Text out of the screen and then scroll back, it has a new Font)

enter image description here

What is odd (or not :P ) works perfectly fine on IOS

enter image description here

tested on both debug and release versions of the Android app, on different devices, different Android SDK level

like image 475
wojciech_maciejewski Avatar asked Nov 15 '25 10:11

wojciech_maciejewski


1 Answers

It has been fixed in 1.6.11


This is a bug of Font composable. Reported it here.

Until it's fixed you can reset it's value manually using key. Use FontHotfix instead of Font for now:

@SuppressLint("ComposableNaming")
@Composable
// TODO: replace with system `Font` when https://github.com/JetBrains/compose-multiplatform/issues/4863 is fixed
fun FontHotfix(
    resource: FontResource,
    weight: FontWeight = FontWeight.Normal,
    style: FontStyle = FontStyle.Normal,
) = key(resource) {
    Font(resource = resource, weight = weight, style = style)
}
like image 65
Philip Dukhov Avatar answered Nov 17 '25 08:11

Philip Dukhov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!