2

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)
    ))
}
devanshu_kaushik
  • 929
  • 11
  • 30
  • Please provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). I tried reproducing it with [this code](https://gist.github.com/PhilipDukhov/e16f5b550be365c439a1cf261d427ff1), and it works fine to me. – Phil Dukhov May 28 '22 at 14:25
  • @PylypDukhov reproducing it is part of the issue, I am using two of the ```CheckoutAddress()``` composables in a ```Column()```, while the first child does not exhibit this behaviour at all, the second one does on first run and after a subsequent recomposition, it too behaves as expected. – devanshu_kaushik May 31 '22 at 13:23
  • Well, that's part of the job that only you can do: remove parts of the code until it stops reproducing to localize the problem. Until I can not reproduce it, I can't help you in any way - it could be a bug or you're doing something wrong in another part of your code. The part you shared looks fine. – Phil Dukhov May 31 '22 at 15:24
  • @devanshu_kaushik you need to provide more info about `CheckoutAddress()` usage – dinhlam Jun 02 '22 at 13:06

0 Answers0