I’m making a custom calendar for a daily planner and I want the calendar to swipe left or right when changing months.enter image description here
I tried to implement this through coroutines and a delay between exit and enter transitions of AnimatedVisibility, but this method seems wrong and buggy to me. To avoid overloading the code, I made a small application with the same animation implementation.
val animDuration = 100
var visible by remember { mutableStateOf(true) }
//Required for variable transitions for each button
val enterTransition = remember { mutableStateOf(EnterTransition.None) }
val exitTransition = remember { mutableStateOf(ExitTransition.None) }
val coroutineScope = rememberCoroutineScope()
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
ButtonLeft {
// Here I change the initialOffsetX of the enter transition
// and the targetOffsetX of the exit transition
// so that the RedBox goes to the right and appears on the left.
enterTransition.value = slideInHorizontally(
initialOffsetX = { -2*it },
animationSpec = tween(animDuration, easing = LinearEasing)
)
exitTransition.value = slideOutHorizontally(
targetOffsetX = { 2*it },
animationSpec = tween(animDuration, easing = LinearEasing)
)
// Here I turn off RedBox visibility,
// wait for the animation end with a delay,
// and then turn on visibility
coroutineScope.launch(context = Dispatchers.Main) {
visible = false
delay(200)
visible = true
}
}
AnimatedVisibility(
visible = visible,
enter = enterTransition.value + fadeIn(tween(animDuration)),
exit = exitTransition.value + fadeOut(tween(animDuration))
) {
RedBox()
}
ButtonRight {
// Here RedBox goes to the left and appears on the right.
enterTransition.value = slideInHorizontally(
initialOffsetX = { 2*it },
animationSpec = tween(animDuration, easing = LinearEasing)
)
exitTransition.value = slideOutHorizontally(
targetOffsetX = { -2*it },
animationSpec = tween(animDuration, easing = LinearEasing)
)
coroutineScope.launch(context = Dispatchers.Main) {
visible = false
delay(200)
visible = true
}
}
}
3