Like what YASAN said, I was able to produce 'slideOut' + 'fadeOut' animation on LazyColumn item using AnimatedVisibility by simply adding isVisible properties on DataClass of your item and wrap your item view in AnimatedVisibility Composable. Since that api is still in experimental please be careful.
For you reference if you or someone else might look for it I'm gonna drop my snippet here.
For the LazyColumn
LazyColumn {
items(
items = notes,
key = { item: Note -> item.id }
) { item ->
AnimatedVisibility(
visible = item.isVisible,
exit = fadeOut(
animationSpec = TweenSpec(200, 200, FastOutLinearInEasing)
)
) {
ItemNote(
item
) {
notes = changeNoteVisibility(notes, it)
}
}
}
}
And for the Item Composable
@ExperimentalAnimationApi
@ExperimentalMaterialApi
@Composable
fun ItemNote(
note: Note,
onSwipeNote: (Note) -> Unit
) {
val iconSize = (-68).dp
val swipeableState = rememberSwipeableState(0)
val iconPx = with(LocalDensity.current) { iconSize.toPx() }
val anchors = mapOf(0f to 0, iconPx to 1)
val coroutineScope = rememberCoroutineScope()
Box(
modifier = Modifier
.fillMaxWidth()
.height(75.dp)
.swipeable(
state = swipeableState,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.5f) },
orientation = Orientation.Horizontal
)
.background(Color(0xFFDA5D5D))
) {
Box(
modifier = Modifier
.fillMaxHeight()
.align(Alignment.CenterEnd)
.padding(end = 10.dp)
) {
IconButton(
modifier = Modifier.align(Alignment.Center),
onClick = {
Log.d("Note", "Deleted")
coroutineScope.launch {
onSwipeNote(note)
}
}
) {
Icon(
Icons.Default.Delete,
contentDescription = "Delete this note",
tint = Color.White
)
}
}
AnimatedVisibility(
visible = note.isVisible,
exit = slideOutHorizontally(
targetOffsetX = { -it },
animationSpec = TweenSpec(200, 0, FastOutLinearInEasing)
)
) {
ConstraintLayout(
modifier = Modifier
.offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
.fillMaxHeight()
.fillMaxWidth()
.background(Color.White)
) {
val (titleText, contentText, divider) = createRefs()
Text(
modifier = Modifier.constrainAs(titleText) {
top.linkTo(parent.top, margin = 12.dp)
start.linkTo(parent.start, margin = 18.dp)
end.linkTo(parent.end, margin = 18.dp)
width = Dimension.fillToConstraints
},
text = note.title,
fontSize = 16.sp,
fontWeight = FontWeight(500),
textAlign = TextAlign.Start
)
Text(
modifier = Modifier.constrainAs(contentText) {
bottom.linkTo(parent.bottom, margin = 12.dp)
start.linkTo(parent.start, margin = 18.dp)
end.linkTo(parent.end, margin = 18.dp)
width = Dimension.fillToConstraints
},
text = note.content,
textAlign = TextAlign.Start
)
Divider(
modifier = Modifier.constrainAs(divider) {
start.linkTo(parent.start)
end.linkTo(parent.end)
bottom.linkTo(parent.bottom)
width = Dimension.fillToConstraints
},
thickness = 1.dp,
color = Color.DarkGray
)
}
}
}
}
Also the data class Note
data class Note(
var id: Int,
var title: String = "",
var content: String = "",
var isVisible: Boolean = true
)