How to change the color of ripple effect of a Button
Asked Answered
G

2

5

For some reason, I'm unable to change the color of the ripple effect of a Button. What am I doing wrong here?

androidx.compose.material.Button(
    onClick = onClick,
    modifier = modifier
        .indication(
            interactionSource = interactionSource,
            indication = rememberRipple(color = Color.Red)
            )
        .navigationBarsPadding(),
    enabled = enabled,
    interactionSource = interactionSource,
    elevation = elevation,
    shape = RectangleShape,
    colors = ButtonDefaults.bottomColors(),
    contentPadding = PaddingValues(vertical = 4.dp),
    content = { Text(text) },
)
Grantham answered 17/1, 2023 at 19:21 Comment(0)
C
4

Your code doesn't work because the ripple is implemented in the clickable modifier defined inside the Button.

However you can change the appearance of the ripple defining a custom RippleTheme and applying it to your composable with the LocalRippleTheme.

Something like:

private object RedRippleTheme: RippleTheme {

    @Composable
    override fun defaultColor() =
        RippleTheme.defaultRippleColor(
            Color.Red, 
            lightTheme = true
        )

    @Composable
    override fun rippleAlpha(): RippleAlpha =
        RippleTheme.defaultRippleAlpha(
            Color.Black,
            lightTheme = true
        )
}

and:

CompositionLocalProvider(LocalRippleTheme provides RedRippleTheme) {
    Button(
       //....
    ){
       //Button content
    }
}

enter image description here

Congenial answered 17/1, 2023 at 21:29 Comment(1)
The RippleTheme.defaultRippleColor(Color.Red, ...) is not a correct way to set a ripple color. The RippleTheme.defaultRippleColor first parameter is a contentColor, not a rippleColor. I don't know why it works for you, but the only thing which works for me is to just use the color directly, like: override fun defaultColor() = Color.Red.Antacid
M
3

Button is derived from this Surface which has its own indication with rememberRipple(). Since Button is as Surface, you can implement clickable with any other Composable that resembles Button

@Composable
fun Button(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    elevation: ButtonElevation? = ButtonDefaults.elevation(),
    shape: Shape = MaterialTheme.shapes.small,
    border: BorderStroke? = null,
    colors: ButtonColors = ButtonDefaults.buttonColors(),
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    content: @Composable RowScope.() -> Unit
) {
    val contentColor by colors.contentColor(enabled)
    Surface(
        onClick = onClick,
        modifier = modifier,
        enabled = enabled,
        shape = shape,
        color = colors.backgroundColor(enabled).value,
        contentColor = contentColor.copy(alpha = 1f),
        border = border,
        elevation = elevation?.elevation(enabled, interactionSource)?.value ?: 0.dp,
        interactionSource = interactionSource,
    ) {
        CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
            ProvideTextStyle(
                value = MaterialTheme.typography.button
            ) {
                Row(
                    Modifier
                        .defaultMinSize(
                            minWidth = ButtonDefaults.MinWidth,
                            minHeight = ButtonDefaults.MinHeight
                        )
                        .padding(contentPadding),
                    horizontalArrangement = Arrangement.Center,
                    verticalAlignment = Alignment.CenterVertically,
                    content = content
                )
            }
        }
    }
}

@Composable
fun Surface(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(color),
    border: BorderStroke? = null,
    elevation: Dp = 0.dp,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit
) {
    val absoluteElevation = LocalAbsoluteElevation.current + elevation
    CompositionLocalProvider(
        LocalContentColor provides contentColor,
        LocalAbsoluteElevation provides absoluteElevation
    ) {
        Box(
            modifier = modifier
                .minimumTouchTargetSize()
                .surface(
                    shape = shape,
                    backgroundColor = surfaceColorAtElevation(
                        color = color,
                        elevationOverlay = LocalElevationOverlay.current,
                        absoluteElevation = absoluteElevation
                    ),
                    border = border,
                    elevation = elevation
                )
                .clickable(
                    interactionSource = interactionSource,
                    indication = rememberRipple(),
                    enabled = enabled,
                    role = Role.Button,
                    onClick = onClick
                ),
            propagateMinConstraints = true
        ) {
            content()
        }
    }
}
Maiolica answered 17/1, 2023 at 19:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.