Jetpack compose: How to use IconToggleButton

Jetpack Compose - IconToggleButton Example

This code demonstrates the usage of IconToggleButton in Jetpack Compose. It creates a simple UI with two icon buttons: a heart icon for "Like" and a floppy disk icon for "Save". Each button toggles its state (liked/unliked, saved/unsaved) when clicked and animates its color accordingly. Additionally, a text element displays the current state of both buttons ("Liked and Saved" or "Unliked and Unsaved").

Breakdown

  1. State Management: The code utilizes remember to create mutable state variables for liked and saved. These variables track the current state (true/false) of each button.
  2. IconToggleButton: The core element is IconToggleButton. It takes two important arguments: checked (current state) and onCheckedChange (callback for state change).
  3. Icon with Animated Color: Inside each IconToggleButton, an Icon is displayed with its color animated based on the button's state. The animateColorAsState function creates a smooth color transition between selected and unselected states.
  4. Text Update: The text element displays the combined state of both buttons using conditional logic. Based on the values of liked and saved, the text reflects "Liked" or "Unliked" and "Saved" or "Unsaved".

Summary

This example effectively showcases how to implement IconToggleButton with state management and animated visuals in Jetpack Compose. It provides a clear and concise way to create interactive buttons with visual feedback, making it easier to build user-friendly interfaces.


MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.IconToggleButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

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

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        val liked = remember { mutableStateOf(true) }
        val saved = remember { mutableStateOf(false) }

        Column(
            Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally) {

            Row(Modifier.padding(16.dp)) {
                IconToggleButton(
                    checked = liked.value,
                    onCheckedChange = { liked.value = it }
                ) {
                    val tint by animateColorAsState(
                        if (liked.value) Color(0xFF7BB661)
                        else Color.LightGray
                    )
                    Icon(
                        Icons.Filled.Favorite,
                        contentDescription = "Localized description",
                        tint = tint
                    )

                }

                IconToggleButton(
                    checked = saved.value,
                    onCheckedChange = { saved.value = it }
                ) {
                    val tint by animateColorAsState(
                        if (saved.value) Color(0xFFEC407A)
                        else Color(0xFFB0BEC5)
                    )
                    Icon(
                        Icons.Filled.Save,
                        contentDescription = "Localized description",
                        tint = tint
                    )
                }
            }

            val isLiked = if (liked.value) "Liked" else "Unliked"
            val isSaved = if (saved.value) "Saved" else "Unsaved"

            Text(
                text = "$isLiked and $isSaved",
                fontWeight = FontWeight.Bold,
                fontSize = 25.sp,
                fontFamily = FontFamily.Serif
            )
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}
More android jetpack compose tutorials