androidandroid-jetpack-composeandroid-jetpack-compose-material3android-compose-card

How do you change card colors on material3 android when pressed?


How to set Background Color for Material3 Card in Android Compose?

Piggy backing fro this question. The answers tells how to set a background color. When material3 card is pressed, it changes color with a ripple effect. But how can I change the effect color when it is pressed?

CardDefaults.cardColors(....) doesn't do it


Solution

  • The Card with the onClick variant uses internally an indication = rememberRipple(). This creates and remembers a Ripple using values provided by RippleTheme.

    You can provide a custom LocalRippleTheme to override the default behaviour:

    CompositionLocalProvider(LocalRippleTheme provides GreenRippleTheme) {
        Card(
            onClick = { /* Do something */ },
            modifier = Modifier.size(width = 180.dp, height = 100.dp)
        ) {
            //Card content
        }
    }
    

    with:

    private object GreenRippleTheme : RippleTheme {
    
        @Composable
        override fun defaultColor() = Color.Green
    
        @Composable
        override fun rippleAlpha(): RippleAlpha = RippleTheme.defaultRippleAlpha(
            Color.Green,
            lightTheme = true
        )
    }
    

    enter image description here


    Otherwise you can use the clickable modifier:

    val interactionSource = remember { MutableInteractionSource() }
    Card(
        modifier = Modifier
            .size(width = 180.dp, height = 100.dp)
            .clickable (
                onClick = { /* Do something */ },
                interactionSource = interactionSource,
                indication = rememberRipple(color = Green )
            )
    ) {
        //Card content
    }
    

    enter image description here


    Finally if you want to modify the background color when the Card is pressed (not the ripple effect) you can use:

        val interactionSource = remember { MutableInteractionSource() }
        val isPressed by interactionSource.collectIsPressedAsState()
        val backgroundColor = if (isPressed) Yellow else MaterialTheme.colorScheme.surfaceVariant
    
        Card(
            interactionSource = interactionSource,
            onClick = { /* Do something */ },
            modifier = Modifier
                .size(width = 180.dp, height = 100.dp),
            colors = CardDefaults.cardColors(
                containerColor = backgroundColor
            )
    
        ) {
            //Card content
        }
    

    enter image description here