user15686227
user15686227

Reputation:

How to use Icon Toggle button in Jetpack Compose?

I want to use Icon button in Jetpack Compose, but I couldn't understand Jetpack Compose docs. Can someone share a sample code for toggle button similar to this one?
When user clicks on a button, I want to animate it like in Instagram with a bounce animation.

Upvotes: 2

Views: 13114

Answers (3)

Dan Alboteanu
Dan Alboteanu

Reputation: 10252

you can use Switch:

var checked by remember { mutableStateOf(true) }
Switch(
  modifier = Modifier.semantics { contentDescription = "Demo" },
  checked = checked,
  onCheckedChange = { checked = it }
)

docs

enter image description here

Upvotes: 1

Psijic
Psijic

Reputation: 1012

Maybe it's a good idea to use Chips instead.

Filter chips use tags or descriptive words to filter content. They can be a good alternative to toggle buttons or checkboxes.

Also it's possible to use Modifier.selectable.

Upvotes: 0

Alex Lipov
Alex Lipov

Reputation: 13958

You can combine IconToggleButton with transitions. Sample code (using version 1.0.0-beta05):

import android.annotation.SuppressLint
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@SuppressLint("UnusedTransitionTargetStateParameter")
@Composable
fun FavoriteButton(
    isChecked: Boolean,
    onClick: () -> Unit
) {
    IconToggleButton(
        checked = isChecked,
        onCheckedChange = { onClick() }
    ) {
        val transition = updateTransition(isChecked, label = "Checked indicator")

        val tint by transition.animateColor(
            label = "Tint"
        ) { isChecked ->
            if (isChecked) Color.Red else Color.Black
        }

        val size by transition.animateDp(
            transitionSpec = {
                if (false isTransitioningTo true) {
                    keyframes {
                        durationMillis = 250
                        30.dp at 0 with LinearOutSlowInEasing // for 0-15 ms
                        35.dp at 15 with FastOutLinearInEasing // for 15-75 ms
                        40.dp at 75 // ms
                        35.dp at 150 // ms
                    }
                } else {
                    spring(stiffness = Spring.StiffnessVeryLow)
                }
            },
            label = "Size"
        ) { 30.dp }

        Icon(
            imageVector = if (isChecked) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
            contentDescription = null,
            tint = tint,
            modifier = Modifier.size(size)
        )
    }
}

@Preview("Favorite Button")
@Composable
fun FavoriteButtonPreview() {
    val (isChecked, setChecked) = remember { mutableStateOf(false) }
    MaterialTheme {
        Surface {
            FavoriteButton(
                isChecked = isChecked, 
                onClick = { setChecked(!isChecked) }
            )
        }
    }
}

These are the required dependencies for this sample:

dependencies {
    implementation 'androidx.core:core-ktx:1.6.0-alpha01'

    implementation "androidx.compose.ui:ui:1.0.0-beta05"
    implementation "androidx.compose.material:material:1.0.0-beta05"
    implementation "androidx.compose.ui:ui-tooling:1.0.0-beta05"
    implementation 'androidx.activity:activity-compose:1.3.0-alpha06'
}

For more details about transition and keyframes and ways to customize them, see Compose's Animation documentation.

Upvotes: 8

Related Questions