https://kotlinlang.org logo
#compose
Title
# compose
a

ascii

09/06/2023, 9:49 PM
I'm trying to transition a button from disabled -> enabled by animating Text color (via ShaderBrush) from the default disabled color -> (let's say) error. The color is supposed to "grow" into fully being
error
, similar to a progress bar filling up. What I have here works, but I was wondering if there's a better way to do it. Reliability/performance.
Copy code
val animationState = remember { AnimationState(0f) }
LaunchedEffect(Unit) { animationState.animateTo(1f, tween(5000)) }

val disabled = MaterialTheme.colorScheme.onSurface.copy(0.38f)
val error = MaterialTheme.colorScheme.error
val offset = animationState.value
val brush = remember(error, disabled, offset) {
    object : ShaderBrush() {
        override fun createShader(size: Size) = LinearGradientShader(
            from = Offset.Zero,
            to = Offset(size.width * offset, 0f),
            colors = listOf(error, disabled),
            colorStops = listOf(offset, 1f),
        )
    }
}

TextButton(
    enabled = offset >= 1f,
    colors = ButtonDefaults.textButtonColors(contentColor = error)
) { Text(style = LocalTextStyle.current.copy(brush)) }
Screenshot examples of what I mean
c

cah

09/07/2023, 1:10 AM
Possibly enabled should be derivedState?
r

romainguy

09/07/2023, 3:24 AM
@cah No because recomposition will happen anyway when offset changes
👍 1
a

ascii

09/07/2023, 1:25 PM
Exactly, it wouldn't matter. What I don't like about this is that I'm creating a new ShaderBrush object for every offset change and that I'm overdrawing perhaps? Button already sets text color, but I'm supplying a brush on top of that.