wbk727
wbk727

Reputation: 8408

How to trigger ripple effect on Switch click for its container

I want to replicate the effect used in the Settings app for Android 12, where the ripple effect is automatically triggered whenever an option is clicked (including the Switch itself). However, in my app, the ripple effect does not happen at all, only the Switch animates.

@Composable
fun ComposableSettingSimpleMode() {
    val isChecked = remember { mutableStateOf(false) }

    Row(modifier = Modifier
        .fillMaxWidth()
        .clickable(onClick = {})) {
        Text(text = stringResource(id = R.string.simple_mode))
        Switch(checked = isChecked.value, onCheckedChange = {
            isChecked.value = it
        })
    }
}

Upvotes: 2

Views: 405

Answers (2)

cd1
cd1

Reputation: 16534

You can use the toggleable modifier:

@Composable
fun ComposableSettingSimpleMode() {
    val isChecked = remember { mutableStateOf(false) }

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .toggleable(
                value = isChecked.value,
                onValueChange = { isChecked.value = it },
            ),
    ) {
        Text(text = "Hello")
        Switch(checked = isChecked.value, onCheckedChange = null)
    }
}

The important points are:

  • The entire row is made "toggleable" (i.e. whatever you want to have the ripple effect on);
  • The toggleable modifier requires a value, which should have the same value as the switch, and an onValueChange, which should perform the actual switch state change (which currently is on the Switch's onCheckedChange);
  • The Switch's onCheckedChange should be set to null, otherwise it will "steal" the click from the row when the Switch is clicked, and the row won't ripple;

Upvotes: 5

AagitoEx
AagitoEx

Reputation: 534

This is where you pass in your own InteractionSource

    var isChecked by remember { mutableStateOf(false) }
    val interactionSource = remember { MutableInteractionSource() }
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(
                interactionSource = interactionSource,
                indication = LocalIndication.current,
                onClick = {
                    isChecked = !isChecked
                }
            )
    ) {
        Text(text = "Dummy Text", Modifier.weight(1f))
        Switch(
            checked = isChecked,
            interactionSource = interactionSource,
            onCheckedChange = {
                isChecked = it
            })
    }

Upvotes: 3

Related Questions