Today, I encountered an error when integrating the rememberRipple() method to enable the ripple effect on the Box widget in Kotlin Compose Multiplatform (KMP). Due to this error, the ripple effect widget displays a warning message about depreciation. Also, the project did not run when I applied the old, deprecated rememberRipple() method. So, after reading the new documentation of the Material library, I found the solution.
Solve rememberRipple has been deprecated Error:
This is what the error looks like:
@Deprecated(level = DeprecationLevel.ERROR, message = “rememberRipple has been deprecated – it returns an old Indication implementation that is not compatible with the new Indication APIs that provide notable performance improvements. Instead, use the new ripple APIs provided by design system libraries, such as material and material3. If you are implementing your own design system library, use createRippleNode to create your own custom ripple implementation that queries your own theme values. For a migration guide and background information, please visit developer. android. com”)
@Suppress(names = {“DEPRECATION”, “TYPEALIAS_EXPANSION_DEPRECATION”})
@Composable
public fun rememberRipple(
bounded: Boolean = true,
radius: Dp = Dp.Unspecified,
color: Color = Color.Unspecified
): Indication
Code with Error:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
@Composable fun SampleBox( buttonText: String, onButtonClick: () -> Unit, ) { val interactionSource = remember { MutableInteractionSource() } val indication = LocalIndication.current Box( modifier = Modifier .padding(18.dp) .background( color = Color(0xFF00B8D4), shape = RoundedCornerShape(8.dp) ) .fillMaxSize() .pointerInput(Unit) { detectTapGestures( onTap = { onButtonClick() }, ) } .clickable( interactionSource = interactionSource, indication = rememberRipple( bounded = true, color = Color.Black, radius = 24.dp ), onClick = { onButtonClick() } ) .padding(horizontal = 24.dp, vertical = 12.dp), contentAlignment = Alignment.Center ) { Text( text = buttonText, color = Color.White, fontSize = 21.sp, ) } } |
Code with Solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@OptIn(ExperimentalFoundationApi::class) @Composable fun SampleBoxFix( buttonText: String, onButtonClick: () -> Unit = {}, onLongPress: () -> Unit = {}, ) { val interactionSource = remember { MutableInteractionSource() } val indication = LocalIndication.current Box( modifier = Modifier .fillMaxSize() .background(Color(0xFF00B8D4), shape = RoundedCornerShape(8.dp)) .indication(interactionSource, indication) // Ripple effect .combinedClickable( interactionSource = interactionSource, indication = null, // Avoid duplicating the ripple effect onClick = { onButtonClick() }, onLongClick = { onLongPress() } ).padding(16.dp), contentAlignment = Alignment.Center ) { Text( text = buttonText, color = Color.White, fontSize = 21.sp, modifier = Modifier.padding(4.dp) ) } } |
Complete source code for App.kt file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
package com.app.test import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.indication import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @Composable fun App() { MaterialTheme { Box(modifier = Modifier.fillMaxSize()) { Column( modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(24.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { SampleBoxFix( buttonText = "Click Me", onButtonClick = { println("Button clicked!") }, onLongPress = { println("Button long clicked!") }, ) } } } } @OptIn(ExperimentalFoundationApi::class) @Composable fun SampleBoxFix( buttonText: String, onButtonClick: () -> Unit = {}, onLongPress: () -> Unit = {}, ) { val interactionSource = remember { MutableInteractionSource() } val indication = LocalIndication.current Box( modifier = Modifier .fillMaxSize() .background(Color(0xFF00B8D4), shape = RoundedCornerShape(8.dp)) .indication(interactionSource, indication) // Ripple effect .combinedClickable( interactionSource = interactionSource, indication = null, // Avoid duplicating the ripple effect onClick = { onButtonClick() }, onLongClick = { onLongPress() } ).padding(16.dp), contentAlignment = Alignment.Center ) { Text( text = buttonText, color = Color.White, fontSize = 21.sp, modifier = Modifier.padding(4.dp) ) } } |
Screenshot: