3 Ways to Disable the Ripple Effect in Jetpack Compose

jetpack compose disable ripple

Today, you will learn how to disable or remove the ripple effect in Android Jetpack Compose.

These are the 3 methods we will discuss:

  1. Using the Mutable Interaction Source
  2. Create a Custom MutableInteractionSource Class
  3. Create a Custom No Ripple Theme

For this article, create a MyUI() composable and call it inside the onCreate() method. We will write our code in it.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            YourProjectNameTheme {
                Surface(
                    modifier = Modifier
                        .fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {
    
}

1. Using the Mutable Interaction Source:

You can use this method if you set the click listener using the Modifier.clickable method. For example, look at the Box below:

@Composable
fun MyUI() {
    
    Box(
        modifier = Modifier
            .size(width = 72.dp, height = 36.dp)
            .background(color = Color.Yellow)
            .clickable {
                // handle click events
            },
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Click Me")
    }
}

Output:

Jetpack Compose Box Ripple

Let’s disable the ripple. First, open the Modifier.clickable() signature.

fun Modifier.clickable(
    interactionSource: MutableInteractionSource,
    indication: Indication?,
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
)

We can disable the ripple using the interactionSource and indication parameters.

The MutableInteractionSource represents the stream of interactions corresponding to the events emitted by the component.

The Indication represents the visual effects that occur when certain interactions happen. For example, showing the ripple effect when a component is pressed. Set its value to null to remove the ripple.

@Composable
fun MyUI() {

    val interactionSource = MutableInteractionSource()

    Box(
        modifier = Modifier
            .size(width = 72.dp, height = 36.dp)
            .background(color = Color.Yellow)
            .clickable(
                interactionSource = interactionSource,
                indication = null
            ) {
                // handle click events
            },
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Click Me")
    }
}

Output:

Box Remove Ripple

2. Create a Custom MutableInteractionSource Class:

This method is helpful when the composable you are working with accepts MutableInteractionSource as the parameter. For example, Switch().

@Composable
fun MyUI() {

    var checked by remember {
        mutableStateOf(false)
    }

    Switch(
        checked = checked,
        onCheckedChange = {
            checked = !checked
        }
    )
}

Output:

Switch Ripple

To disable the ripple, create a custom MutableInteractionSource Class.

class NoRippleInteractionSource : MutableInteractionSource {

    override val interactions: Flow<Interaction> = emptyFlow()

    override suspend fun emit(interaction: Interaction) {}
    
    override fun tryEmit(interaction: Interaction) = true
}

Create an object of this class and pass it to the Switch.

@Composable
fun MyUI() {

    var checked by remember {
        mutableStateOf(false)
    }

    Switch(
        checked = checked,
        onCheckedChange = {
            checked = !checked
        },
        interactionSource = NoRippleInteractionSource()
    )
}

class NoRippleInteractionSource : MutableInteractionSource {

    override val interactions: Flow<Interaction> = emptyFlow()

    override suspend fun emit(interaction: Interaction) {}
    
    override fun tryEmit(interaction: Interaction) = true
}

Output:

Switch Remove Ripple

3. Create a Custom No Ripple Theme:

You can use this method when you want to disable the ripple on multiple composables.

Create a custom theme and remove the ripple color and alpha.

private object NoRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = Color.Unspecified

    @Composable
    override fun rippleAlpha(): RippleAlpha = RippleAlpha(0.0f,0.0f,0.0f,0.0f)
}

Apply it to the composables.

@Composable
fun MyUI() {

    CompositionLocalProvider(LocalRippleTheme provides NoRippleTheme) {
        // add your composables here

        Box(
            modifier = Modifier
                .size(width = 72.dp, height = 36.dp)
                .background(color = Color.Yellow)
                .clickable {
                    // handle click events
                },
            contentAlignment = Alignment.Center
        ) {
            Text(text = "Click Me")
        }
    }
}

private object NoRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = Color.Unspecified

    @Composable
    override fun rippleAlpha(): RippleAlpha = RippleAlpha(0.0f,0.0f,0.0f,0.0f)
}

Output:

Box Remove Ripple

How to Disable Ripple Effect on Jetpack Compose Button?

We can disable the ripple effect on Button() in 2 ways.

1. Using Mutable Interaction Source Parameter:

The Button() composable takes MutableInteractionSource as a parameter. So, we can use the second method.

@Composable
fun MyUI() {
    Button(
        onClick = {
            // handle click events
        },
        interactionSource = NoRippleInteractionSource()
    ) {
        Text(text = "Click")
    }
}

class NoRippleInteractionSource : MutableInteractionSource {

    override val interactions: Flow<Interaction> = emptyFlow()

    override suspend fun emit(interaction: Interaction) {}

    override fun tryEmit(interaction: Interaction) = true
}

Output:

Button disable ripple

2. Create a Button Using the Box:

We can also create a button using the Box and apply the first method.

@Composable
fun MyUI() {

    val interactionSource = MutableInteractionSource()

    Box(
        modifier = Modifier
            .size(width = 80.dp, height = 36.dp)
            .background(
                color = Color.Magenta,
                shape = RoundedCornerShape(percent = 12)
            )
            .clickable(
                interactionSource = interactionSource,
                indication = null
            ) {
                // handle click events
            },
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "Click Me",
            color = Color.White
        )
    }
}

Output:

Jetpack compose disable ripple Theme

Related: Shapes in Jetpack Compose

These are the different ways to disable the ripple in Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Related:

4 thoughts on “3 Ways to Disable the Ripple Effect in Jetpack Compose”

Leave a Comment