Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify ripple color of IconButton in Jetpack Compose

How can I change the ripple color of an IconButton?

I tried doing it this way, but it doesn't change:

IconButton(
        onClick = { onClick() },
        modifier = Modifier.clickable(
          onClick = { onClick() },
          indication = rememberRipple(color = MyCustomTheme.colors.primary),
          interactionSource =  remember { MutableInteractionSource() },
        )
      )
like image 543
Praveen P. Avatar asked Apr 26 '21 10:04

Praveen P.


2 Answers

I don't know if you found a way to make it work for the whole app but I found a way to do so. So I'm posting this incase someone else has a similar issue.

You can set the custom RippleTheme object as described by Gabriele Mariotti's answer then you can pass the CompositionLocalProvider() as content in MaterialTheme. The content from the app's theme can then be set as content for CompositionalLocalProvider().

Take a look here:

private object JetNewsRippleTheme : RippleTheme {
    // Here you should return the ripple color you want
    // and not use the defaultRippleColor extension on RippleTheme.
    // Using that will override the ripple color set in DarkMode
    // or when you set light parameter to false
    @Composable
    override fun defaultColor(): Color = MaterialTheme.colors.primary

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

Then for your app theme it should be:

@Composable
fun JetNewsTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = if (darkTheme) DarkColors else LightColors,
        typography = JetNewsTypography,
        shapes = JetNewsShapes
    ) {
        CompositionLocalProvider(
            LocalRippleTheme provides JetNewsRippleTheme,
            content = content
        )
    }
}

This method should work for the whole app unless you explicitly set another RippleTheme directly to Composables below the AppTheme hierarchy. And it doesn't conflict with other types of ComposableLocalProvider values you may set directly to your other Composables.

like image 113
Racka98 Avatar answered Oct 13 '22 23:10

Racka98


Your code doesn't work since the Ripple is implemented in a .clickable modifier defined inside the IconButton.

The appearance of the Ripples is based on a RippleTheme and you can define a custom RippleTheme and apply to your composable with the LocalRippleTheme.

Something like:

private object RippleCustomTheme: RippleTheme {

    //Your custom implementation...
    @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  RippleCustomTheme) {
    IconButton(
        onClick = { },
    ) {
        Icon(Icons.Filled.Add, "")
    }
}

enter image description hereenter image description here

like image 28
Gabriele Mariotti Avatar answered Oct 14 '22 01:10

Gabriele Mariotti