You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose Multiplatform Android端Text字体切换不即时更新问题

Compose Multiplatform Android端字体切换不即时问题修复

问题现象

开发的阅读器应用支持字号、颜色、字体切换,基于Compose Multiplatform 1.6.10、Kotlin 2.0.0和Compose Resources技术栈开发。iOS端字体切换功能正常,但Android端存在异常:点击切换字体后,Text组件虽触发重组,但屏幕上字体无即时变化,只有当Text滚出屏幕再返回时,才会显示新字体。已覆盖debug/release版本、不同设备及Android SDK级别完成测试。

核心实现代码如下:

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)))
                    )
                }
            }
        }
        // 简化部分代码
        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
            )
        }
    }
}

问题根源

Android端Compose对FontResource的重组感知存在延迟,直接在Text的style参数中创建FontFamily(Font(styleState.fontFamily...))时,Compose无法正确识别字体资源的变化,导致当前可见的LazyColumn列表项不会触发重新测量与绘制,只有当列表项被回收复用(滚出屏幕)时,才会重新加载新字体。

修复方案

方案1:将FontFamily包装为可观察State

通过remember结合derivedStateOf,基于styleState.fontFamily创建可观察的FontFamily实例,确保字体变化能触发Compose的正确重组流程:

@Composable
fun TestScreen() {
    var styleState by remember {
        mutableStateOf(Style())
    }
    
    // 绑定字体资源状态,创建可观察的FontFamily
    val fontFamily by remember(styleState.fontFamily) {
        derivedStateOf {
            FontFamily(Font(styleState.fontFamily, FontWeight.Normal))
        }
    }
    
    Column(modifier = Modifier.background(Color.White)) {
        LazyColumn(modifier = Modifier.weight(1.0f), verticalArrangement = Arrangement.spacedBy(24.dp)) {
            items(101) { // 改用items符合LazyColumn最佳实践
                Text(
                    staticText,
                    style = style.copy(
                        color = styleState.color,
                        fontSize = styleState.fontSize.sp,
                        fontFamily = fontFamily
                    )
                )
            }
        }
        // 下方字体切换按钮代码保持不变
    }
}

方案2:为LazyColumn项添加字体绑定的Key

为每个LazyColumn的item添加与字体资源绑定的key,当字体变化时强制列表项重新组合:

LazyColumn(modifier = Modifier.weight(1.0f), verticalArrangement = Arrangement.spacedBy(24.dp)) {
    for (i in 0..100) {
        item(key = styleState.fontFamily) { // 绑定字体资源作为key
            Text(
                staticText,
                style = style.copy(
                    color = styleState.color,
                    fontSize = styleState.fontSize.sp,
                    fontFamily = FontFamily(Font(styleState.fontFamily, FontWeight.Normal))
                )
            )
        }
    }
}

方案3:升级Compose Multiplatform版本

部分旧版本的Compose Multiplatform在Android端存在字体资源重组的底层bug,升级到1.7.0及以上版本(需同步适配对应Kotlin版本)可能直接解决该问题。

验证说明

上述方案修复后,点击字体切换按钮,Android端的Text组件会即时更新字体,无需滚动出屏幕。方案1更符合Compose状态管理的最佳实践,方案2则属于轻量化的快速修复方案,可根据项目需求选择。

内容的提问来源于stack exchange,提问作者wojciech_maciejewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:41:25