我正在使用 SwipeToDismiss (Material3) 来滑动和消除列表中的项目。它工作正常,但我想第一次向用户显示一个小动画,以便看到他能够滑动并消除列表中的项目。基本上我想显示一个小的滑动(例如 20 dp),然后返回到初始状态。
为了实现动画,我这样做了:
@Composable
fun AnimatedItem(
onMeasuredHeight: (Dp) -> Unit = {}
) {
val animationDuration = 2000
val localDensity = LocalDensity.current
var height by remember {
mutableStateOf(0.dp)
}
var width by remember {
mutableStateOf(0.dp)
}
var isVisible by remember {
mutableStateOf(false)
}
Box(
modifier = Modifier
.background(
color = Color.White,
shape = RoundedCornerShape(8.dp)
)
.onGloballyPositioned { coordinates ->
height = with(localDensity) { coordinates.size.height.toDp() }
width = with(localDensity) { coordinates.size.width.toDp() }
onMeasuredHeight(height)
}
) {
AnimatedVisibility(
modifier = Modifier.align(Alignment.CenterEnd),
visible = isVisible,
enter = fadeIn(animationSpec = tween(durationMillis = animationDuration)) +
expandHorizontally(
expandFrom = Alignment.End,
animationSpec = tween(
durationMillis = animationDuration,
easing = FastOutSlowInEasing,
)
),
exit = fadeOut(
animationSpec = tween(
durationMillis = animationDuration,
easing = FastOutSlowInEasing,
)
) + shrinkHorizontally(
shrinkTowards = Alignment.End,
animationSpec = tween(
durationMillis = animationDuration,
easing = FastOutSlowInEasing,
)
)
) {
// the animated view
Box(
modifier = Modifier
.width(32.dp)
.height(height)
.background(
color = Color.Red,
shape = RoundedCornerShape(
topEnd = 8.dp,
bottomEnd = 8.dp
)
)
)
}
LaunchedEffect(Unit) {
delay(500)
isVisible = true
delay(1000)
isVisible = false
}
// the info view that does not pushed when red box enters
Column(
modifier = Modifier.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 1",
style = MaterialTheme.typography.headlineMedium
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 2",
style = MaterialTheme.typography.headlineMedium
)
}
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 3",
style = MaterialTheme.typography.titleMedium
)
Text(
modifier = Modifier.padding(top = 2.dp),
text = "text 4",
style =MaterialTheme.typography.titleMedium,
)
}
}
}
因此,我可以看到动画(从头到尾进入的红色视图),但我的问题是:有没有办法让它像红色视图“推动”剩余视图?现在就像红色框位于另一个框上方,并且在进入屏幕时不会推动现有框。
我尝试使用包含信息视图和动画视图(红色框)的行,但动画根本不起作用。
欢迎任何帮助
我错误地寻求了解决方案。
基本上,我在背景上添加了一个红色视图,并在其顶部添加了我的实际行项目视图。所以随着使用 offsetAnimation 我有所需的滑动动画(时间可以根据我们的需要调整)。我的行项目视图从末尾滑动到开头,红色背景变得可见。然后返回初始状态。
@Composable
fun AnimatedItem() {
val startDelay = 500L
val endDelay = 800L
var isVisible by remember {
mutableStateOf(false)
}
val targetValue: Dp = if (isVisible) {
20.dp
} else {
0.dp
}
val offsetAnimation: Dp by animateDpAsState(
targetValue = targetValue,
label = "",
animationSpec = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
)
)
Box(
modifier = Modifier
.background(
color = Color.Red,
shape = RoundedCornerShape(8.dp)
)
) {
Row(
modifier = Modifier
.fillMaxSize()
.offset(x = -offsetAnimation)
.background(
color = Color.White,
shape = RoundedCornerShape(8.dp)
)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 1",
style = MaterialTheme.typography.headlineMedium
)
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 2",
style = MaterialTheme.typography.headlineMedium
)
}
Text(
modifier = Modifier.padding(top = 8.dp),
text = "text 3",
style = MaterialTheme.typography.titleMedium
)
Text(
modifier = Modifier.padding(top = 2.dp),
text = "text 4",
style = MaterialTheme.typography.titleMedium,
)
}
LaunchedEffect(Unit) {
delay(startDelay)
isVisible = true
delay(endDelay)
isVisible = false
}
}
}
}