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

Jetpack Compose 1.2.0中withStyle调用stringResource报错的简洁解决办法

解决Jetpack Compose 1.2.0+中buildAnnotatedString内调用stringResource的编译错误

问题场景

此前大量使用withStyle构建带格式的注解字符串,例如要显示:

OPTION A or OPTION B

编写的代码如下:

val optionAorB = buildAnnotatedString {
    withStyle(MaterialTheme.typography.h2.toSpanStyle()) { append(stringResource(R.string.option_a)) }
    withStyle(MaterialTheme.typography.body2.toSpanStyle()) { append(stringResource(R.string.or)) }
    withStyle(MaterialTheme.typography.h2.toSpanStyle()) { append(stringResource(R.string.option_b)) }
}

升级到Jetpack Compose 1.2.0版本后,编译器抛出错误:
@Composable invocations can only happen from the context of a @Composable function

已知将stringResource移至withStyle的lambda代码块外可解决问题,但大量修改会导致代码混乱,需要更简洁的方案。

解决方案:自定义带Composable上下文的withStyle扩展函数

创建一个AnnotatedString.Builder的扩展函数,让其lambda参数支持@Composable上下文,这样就能在内部继续调用stringResource:

@Composable
fun AnnotatedString.Builder.withComposableStyle(
    style: SpanStyle,
    content: @Composable AnnotatedString.Builder.() -> Unit
) {
    val styledString = buildAnnotatedString(content)
    pushStyle(style)
    append(styledString)
    pop()
}

使用方式

只需将原有代码中的withStyle替换为withComposableStyle即可:

val optionAorB = buildAnnotatedString {
    withComposableStyle(MaterialTheme.typography.h2.toSpanStyle()) { 
        append(stringResource(R.string.option_a)) 
    }
    withComposableStyle(MaterialTheme.typography.body2.toSpanStyle()) { 
        append(stringResource(R.string.or)) 
    }
    withComposableStyle(MaterialTheme.typography.h2.toSpanStyle()) { 
        append(stringResource(R.string.option_b)) 
    }
}

原理说明

Jetpack Compose 1.2.0之后,官方的AnnotatedString.Builder.withStyle的lambda参数不再标记为@Composable,而stringResource是必须在@Composable上下文中调用的函数,因此原有写法触发编译错误。

自定义的withComposableStyle通过内部调用Composable版本的buildAnnotatedString,让传入的contentlambda拥有@Composable上下文,从而允许调用stringResource,最后将生成的带格式字符串追加到当前Builder中并应用指定样式。

这种方式只需全局替换函数名(可通过IDE的批量替换功能完成),无需逐个迁移stringResource,大幅减少代码修改量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:45:31