使用带注释的字符串组合的文本意外地占据了与放置在同一行中的button()相同的颜色

发布于 2025-02-01 13:56:17 字数 3093 浏览 2 评论 0原文

我构建了一个合成的可结合,基本上是一个row,其中包含一个地址为textbutton以及旁边。该地址在其中包含一个标签(例如“账单为:'),并且要对其进行略有不同的格式,我正在使用buildantAntatedString函数。

这很简单,但是我注意到第一次运行期间,地址文本将分配给button Composable分配的颜色。我已经通过更改按钮颜色来验证这一点,并且每次在第一次运行中结果相同。在随后的运行中,可组合的行为符合预期,即文本被呈现为text-style中指定的黑色。谁能解释一下为什么会发生这种情况,或者让我知道是否应该将其作为Jetpack组成团队的问题记录?

屏幕截图 首次运行的模拟器(也在物理Redmi设备上复制):

屏幕截图代表随后的运行预期行为

我的可组合函数:

@Composable
fun CheckoutAddress(
    modifier: Modifier = Modifier,
    addressLabel: String,
    address: String?,
    onChangeClick: () -> Unit
) {
    val separator = ": "
    val addressText = buildAnnotatedString {
        appendMedium(addressLabel)
        appendMedium(separator)
        addStyle(
            SpanStyle(
                fontSize = MaterialTheme.typography.body1.fontSize
            ),
            start = 0,
            end = "$addressLabel$separator".length - 1
        )
        if(address.isNullOrBlank()) {
            appendColored(stringResource(id = R.string.label_not_set), color = MaterialTheme.colors.error)
        } else {
            append(address)
        }
    }
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {

        Text(
            modifier = Modifier
                .weight(1f)
                .padding(end = CONTENT_TO_BUTTON_PADDING.dp),
            text = addressText,
            style = MaterialTheme.typography.body2,
            maxLines = 4,
            overflow = TextOverflow.Ellipsis
        )

        ChangeButton(
            onClick = onChangeClick
        )
    }
}

changebutton composable r.colors.default_blue composable范围内指定的颜色由注释的字符串文本更改并验证):

@Composable
fun ChangeButton(
    modifier: Modifier = Modifier,
    onClick: () -> Unit
) {
    TextButton(
        modifier = modifier,
        onClick = onClick,
        colors = ButtonDefaults.textButtonColors(contentColor = colorResource(id = R.color.defaultBlue))
    ) {
        Text(
            text = stringResource(id = R.string.label_change_button).uppercase()
        )
    }
}

上面使用的注释字符串辅助方法

fun AnnotatedString.Builder.appendMedium(text: String) {
    append(AnnotatedString(text, SpanStyle(fontWeight = FontWeight.Medium)))
}

fun AnnotatedString.Builder.appendColored(text: String, color: androidx.compose.ui.graphics.Color) {
    append(AnnotatedString(
        text,
        SpanStyle(color = color)
    ))
}

I built a composable which is basically a Row containing an address as Text and a Button alongside it. The address contains a label within it (e.g. 'Bill To: ') and to format it slightly differently I am using the buildAnnotatedString function.

This is pretty straightforward, but I am noticing an issue when during the first run, the address Text takes the colour assigned to the Button composable. I have verified this by changing the Button colour, and each time the result is the same on the first run. On subsequent runs, the composable behaves as expected, i.e. the Text is rendered as black as specified in the text-style. Can anyone please explain why this happens or let me know if this should be logged as an issue with the Jetpack Compose team?

Screenshot from the emulator of the first run (reproduced on physical Redmi devices as well):
screenshot of the issue

Screenshot representing subsequent runs and the expected behaviour:
screenshot of the expected behaviour

My Composable function:

@Composable
fun CheckoutAddress(
    modifier: Modifier = Modifier,
    addressLabel: String,
    address: String?,
    onChangeClick: () -> Unit
) {
    val separator = ": "
    val addressText = buildAnnotatedString {
        appendMedium(addressLabel)
        appendMedium(separator)
        addStyle(
            SpanStyle(
                fontSize = MaterialTheme.typography.body1.fontSize
            ),
            start = 0,
            end = "$addressLabel$separator".length - 1
        )
        if(address.isNullOrBlank()) {
            appendColored(stringResource(id = R.string.label_not_set), color = MaterialTheme.colors.error)
        } else {
            append(address)
        }
    }
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {

        Text(
            modifier = Modifier
                .weight(1f)
                .padding(end = CONTENT_TO_BUTTON_PADDING.dp),
            text = addressText,
            style = MaterialTheme.typography.body2,
            maxLines = 4,
            overflow = TextOverflow.Ellipsis
        )

        ChangeButton(
            onClick = onChangeClick
        )
    }
}

The ChangeButton composable (The R.colors.default_blue colour specified within this composable's scope is taken up by the annotated string Text, have changed its value and verified) :

@Composable
fun ChangeButton(
    modifier: Modifier = Modifier,
    onClick: () -> Unit
) {
    TextButton(
        modifier = modifier,
        onClick = onClick,
        colors = ButtonDefaults.textButtonColors(contentColor = colorResource(id = R.color.defaultBlue))
    ) {
        Text(
            text = stringResource(id = R.string.label_change_button).uppercase()
        )
    }
}

The Annotated String helper methods used above:

fun AnnotatedString.Builder.appendMedium(text: String) {
    append(AnnotatedString(text, SpanStyle(fontWeight = FontWeight.Medium)))
}

fun AnnotatedString.Builder.appendColored(text: String, color: androidx.compose.ui.graphics.Color) {
    append(AnnotatedString(
        text,
        SpanStyle(color = color)
    ))
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文