What is clickable indication in jetpack compose?

Viewed 244

Hey guys I am doing background selector in jetpack compose. I asked different question regarding background click question. I noticed when I am using

indication = LocalIndication.current

inside my Modifier.clickable and when trying to click it shows very different dark in color which I don't want. You can check in this video. When I changed to

indication = rememberRipple(true)

it showing me correct color which I want to show. I tried to see in the document to understand what is the use of this. Can someone guide me what is the use of this and explain me different types we can use inside this indication. Thanks

1 Answers

indication indication to be shown when modified element is pressed. Be default, indication from [LocalIndication] will be used. Pass null to show no indication, or current value from [LocalIndication] to show theme default

Indication is by default ripple effect when you click an item

You can get it from your theme, use rememberRipple or you can write you own your Indication

Examples below and more is available in this tutorial for Compose. You can test it

With rememberRipple()

@Composable
fun CustomRippleExample() {

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {
        Box(
            contentAlignment = Alignment.Center,
            modifier = modifierWithClip
                .clickable(
                    interactionSource = MutableInteractionSource(),
                    indication = rememberRipple(
                        bounded = true,
                        radius = 250.dp,
                        color = Color.Green
                    ),
                    onClick = {}
                )
        ) {
            Text(
                text = "rememberRipple() bounded",
                color = Color.White
            )
        }

        Spacer(modifier = Modifier.height(8.dp))

        Box(
            contentAlignment = Alignment.Center,
            //  Modifier.clip also bounds ripple
            modifier = modifierNoClip
                .clickable(
                    interactionSource = MutableInteractionSource(),
                    indication = rememberRipple(
                        bounded = false,
                        radius = 250.dp,
                        color = Color.Green
                    ),
                    onClick = {}
                )
        ) {
            Text(
                text = "rememberRipple() unbounded",
                color = Color.White
            )
        }
    }
}

From your theme

@Composable
fun CustomRippleThemeExample() {

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {

        CompositionLocalProvider(LocalRippleTheme provides CustomRippleTheme(Color.Cyan)) {
            Box(
                modifier = modifierWithClip.clickable {},
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = "Custom Ripple Theme",
                    color = Color.White
                )
            }
        }

        Spacer(modifier = Modifier.height(8.dp))

        CompositionLocalProvider(LocalRippleTheme provides CustomRippleTheme(Color.Magenta)) {
            Box(
                modifier = modifierWithClip.clickable {},
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = "Custom Ripple Theme",
                    color = Color.White
                )
            }
        }
    }
}

Custom Indication

private class CustomIndication(
    val pressColor: Color = Color.Red,
    val cornerRadius: CornerRadius = CornerRadius(16f, 16f),
    val alpha: Float = 0.5f,
    val drawRoundedShape: Boolean = true
) : Indication {

    private inner class DefaultIndicationInstance(
        private val isPressed: State<Boolean>,
    ) : IndicationInstance {

        override fun ContentDrawScope.drawIndication() {

            drawContent()
            when {
                isPressed.value -> {
                    if (drawRoundedShape) {
                        drawRoundRect(
                            cornerRadius = cornerRadius,
                            color = pressColor.copy(
                                alpha = alpha
                            ), size = size
                        )
                    } else {

                        drawCircle(
                            radius = size.width,
                            color = pressColor.copy(
                                alpha = alpha
                            )
                        )
                    }
                }
            }
        }
    }

    @Composable
    override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
        val isPressed = interactionSource.collectIsPressedAsState()
        return remember(interactionSource) {
            DefaultIndicationInstance(isPressed)
        }
    }
}

Example

@Composable
fun CustomIndicationExample() {

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
    ) {


        val indication1: CustomIndication = CustomIndication(
            pressColor = Color.Cyan,
            cornerRadius = CornerRadius(30f, 30f),
            alpha = .7f
        )

        val indication2: CustomIndication = CustomIndication(
            pressColor = Color.Red,
            cornerRadius = CornerRadius(16f, 16f),
            alpha = .5f
        )

        val indication3: CustomIndication = CustomIndication(
            pressColor = Color(0xffFFEB3B),
            alpha = .4f,
            drawRoundedShape = false,
        )

        Box(
            modifierWithClip
                .clickable(
                    interactionSource = MutableInteractionSource(),
                    indication = indication1,
                    onClick = {}
                ),
            contentAlignment = Alignment.Center) {
            Text(
                text = "Custom Indication",
                color = Color.White
            )
        }

        Spacer(modifier = Modifier.height(8.dp))

        Box(
            modifierWithClip
                .clickable(
                    interactionSource = MutableInteractionSource(),
                    indication = indication2,
                    onClick = {}
                ),
            contentAlignment = Alignment.Center) {
            Text(
                text = "Custom Indication",
                color = Color.White
            )
        }

        Spacer(modifier = Modifier.height(8.dp))

        Box(
            Modifier.fillMaxWidth()
                .height(200.dp)
                .clickable(
                    interactionSource = MutableInteractionSource(),
                    indication = indication3,
                    onClick = {}
                ),
            contentAlignment = Alignment.Center) {
            Text(
                text = "Custom Indication with Circle Shape",
                color = Color.White
            )
        }
    }
}
Related