Skip to content

Instantly share code, notes, and snippets.

@ardakazanci
Created May 10, 2025 13:34
Show Gist options
  • Save ardakazanci/daddf99de4e8adbc3c67e14bac7a8a72 to your computer and use it in GitHub Desktop.
Save ardakazanci/daddf99de4e8adbc3c67e14bac7a8a72 to your computer and use it in GitHub Desktop.
CheckBox Switcher with Jetpack Compose
@Composable
fun CheckBoxSwitcherComponent() {
var isChecked by remember { mutableStateOf(false) }
var cornerRadius by remember { mutableStateOf(16f) }
var shadowElevation by remember { mutableStateOf(12f) }
var scaleFactor by remember { mutableStateOf(0.93f) }
var iconSize by remember { mutableStateOf(24f) }
val sliderColors = SliderDefaults.colors(
thumbColor = Color(0xFF4CAF50),
activeTrackColor = Color(0xFF4CAF50),
inactiveTrackColor = MaterialTheme.colorScheme.secondaryContainer,
)
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF0F0F0))
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CheckboxSwitcher(
checked = isChecked,
onCheckedChange = { isChecked = it },
modifier = Modifier,
cornerRadius = cornerRadius.dp,
shadowElevation = shadowElevation.dp,
scalePressed = scaleFactor,
iconSize = iconSize.dp
)
Spacer(modifier = Modifier.height(120.dp))
Text("Corner Radius: ${cornerRadius.toInt()} dp")
Slider(
colors = sliderColors,
value = cornerRadius,
onValueChange = { cornerRadius = it },
valueRange = 0f..32f
)
Text("Shadow Elevation: ${shadowElevation.toInt()} dp")
Slider(
colors = sliderColors,
value = shadowElevation,
onValueChange = { shadowElevation = it },
valueRange = 0f..24f
)
Text("Pressed Scale: ${String.format("%.2f", scaleFactor)}")
Slider(
colors = sliderColors,
value = scaleFactor,
onValueChange = { scaleFactor = it },
valueRange = 0.85f..1f
)
Text("Icon Size: ${iconSize.toInt()} dp")
Slider(
colors = sliderColors,
value = iconSize,
onValueChange = { iconSize = it },
valueRange = 12f..36f
)
}
}
@Composable
fun CheckboxSwitcher(
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
modifier: Modifier = Modifier,
cornerRadius: Dp = 16.dp,
shadowElevation: Dp = 12.dp,
scalePressed: Float = 0.93f,
iconSize: Dp = 24.dp
) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val scale by animateFloatAsState(
targetValue = if (isPressed) scalePressed else 1f,
animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy)
)
val transition = updateTransition(targetState = checked, label = "CheckboxTransition")
val knobOffset by transition.animateDp(label = "Offset") { isChecked ->
if (isChecked) 52.dp else 6.dp
}
val knobColor by transition.animateColor(label = "KnobColor") { isChecked ->
if (isChecked) Color(0xFF4CAF50) else Color(0xFFE0E0E0)
}
val iconAlpha by transition.animateFloat(label = "IconAlpha") { isChecked ->
if (isChecked) 1f else 0f
}
Box(
modifier = modifier
.size(width = 112.dp, height = 56.dp)
.scale(scale)
.shadow(shadowElevation, shape = RoundedCornerShape(cornerRadius), clip = false)
.clip(RoundedCornerShape(cornerRadius))
.background(Color.White)
.clickable(
interactionSource = interactionSource,
indication = null,
onClick = { onCheckedChange(!checked) }
),
contentAlignment = Alignment.CenterStart
) {
Box(
modifier = Modifier
.padding(6.dp)
.offset(x = knobOffset)
.size(44.dp)
.clip(RoundedCornerShape(cornerRadius / 1.5f))
.background(knobColor),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.Default.Check,
contentDescription = "Check",
tint = Color.White,
modifier = Modifier
.size(iconSize)
.alpha(iconAlpha)
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment