I have a row with 4 buttons, and depending on a flag isOn
, a couple of buttons need to be visible/invisible with an animation. Here are the rules:
- button 1: visible if
isOn=true
- button 2: always visible
- button 3: visible if
isOn=false
- button 4: always visible
Here is a sample code of what I already have:
private val actionButtonSize = 67.dp
@Composable
internal fun ExampleButtons(
modifier: Modifier = Modifier,
isOn: Boolean,
) {
val button3Visible by remember(isOn) {
mutableStateOf(isOn)
}
val button1Visible by remember(isOn) {
mutableStateOf(!isOn)
}
Box(modifier = modifier) {
Row(
modifier = Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
// button 1
AnimatedVisibility(
visible = button1Visible,
enter = slideInHorizontally(
initialOffsetX = { fullWidth -> -fullWidth }
) + fadeIn(),
exit = slideOutHorizontally(
targetOffsetX = { fullWidth -> -fullWidth }
) + fadeOut()
) {
IconButton(
modifier = Modifier
.size(actionButtonSize)
.clip(CircleShape)
.background(color = Color.Red),
onClick = { }
) { }
}
// button 2
IconButton(
modifier = Modifier
.size(actionButtonSize)
.clip(CircleShape)
.background(color = Color.Green),
onClick = { }
) { }
// button 3
AnimatedVisibility(
visible = button3Visible,
enter = slideInHorizontally(
initialOffsetX = { fullWidth -> fullWidth }
) + fadeIn(),
exit = slideOutHorizontally(
targetOffsetX = { fullWidth -> fullWidth }
) + fadeOut()
) {
IconButton(
modifier = Modifier
.size(actionButtonSize)
.clip(CircleShape)
.background(color = Color.Blue),
onClick = { }
) { }
}
// button 4
IconButton(
modifier = Modifier
.size(actionButtonSize)
.clip(CircleShape)
.background(color = Color.Magenta),
onClick = { }
) { }
}
}
}
@Preview(
widthDp = 300,
)
@Composable
fun ExampleButtonsWithAnimationPreview() {
var isOn: Boolean by remember {
mutableStateOf(false)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
ExampleButtons(
modifier = Modifier
.height(150.dp),
isOn = isOn
)
Button(onClick = {
isOn = !isOn
}) {
Text(
text = if (isOn) {
"Off"
} else {
"On"
}
)
}
}
}
The animation does what I want, but it is not smooth, and the "button 4" changes it's position during the animation, while I would like it to be at the same position everytime.
Here is how it looks like now:
What am I missing here?