I use AnimatedVisibility
to animate deleting an item from a LazyColumn
together with MutableTransitionState
to catch the end of animation to delete this item from LazyColumn
's list.
I composed a handy extension function for this:
@ExperimentalTransitionApi
fun MutableTransitionState<Boolean>.transitionState(): TransitionState =
if (this.isIdle && this.currentState) TransitionState.Visible
else if (this.isIdle && !this.currentState) TransitionState.Invisible
else if (!this.isIdle && this.currentState) TransitionState.Disappearing
else TransitionState.Appearing
enum class TransitionState(private val whatever: Int) {
Visible(1),
Appearing(2),
Invisible(-1),
Disappearing(-2)
}
It is correct in a sense that it returns correct values (tested), but currentState
appears to be false
only initially, so I can't catch the only event I'm interested in - Invisible
.
Here is my LazyColumn
:
val items by viewModel.itemsFlow.collectAsState()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(10.dp),
contentPadding = PaddingValues(horizontal = 15.dp, vertical = 15.dp)
) {
items(items) { item ->
val animationState = remember {
MutableTransitionState(false) // The only time currentState is false!
}.apply { targetState = true }
AnimatedVisibility(
visibleState = animationState,
enter = slideInVertically() + fadeIn(),
exit = slideOutHorizontally(
targetOffsetX = { it*2 },
animationSpec = tween(
durationMillis = 700
)
)
) {
ItemCard(
item = item,
viewModel = viewModel,
animationState = animationState
)
}
}
}
My ItemCard
has a Button
that changes animationState.tagetValue
to false
, and the state is logged inside the card:
Card {
Log.v("ANIMATION", "View ${item.name} is now ${animationState.transitionState().name}")
Log.v("ANIMATION", "View ${item.name} has values: isIdle = ${animationState.isIdle}, currentState = ${animationState.currentState}")
/*...*/
Button(
/*...*/
onClick = {
animationState.targetState = false
}
) {/*...*/}
}
My logs, quite unfortunately, are like this:
V/ANIMATION: View name is now Appearing
V/ANIMATION: View name has values: isIdle = false, currentState = false
V/ANIMATION: View name is now Appearing
V/ANIMATION: View name has values: isIdle = false, currentState = false
V/ANIMATION: View name is now Visible
V/ANIMATION: View name has values: isIdle = true, currentState = true
V/ANIMATION: View name is now Visible
V/ANIMATION: View name has values: isIdle = true, currentState = true
// After I click the button:
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true
So where's the invisible state, i.e. false
currentState
? Have I done something wrong?