Jetpack Compose:如何通过代码触发AnimatedVisibility进入动画?
问题:如何在ContentList组件外部触发Empty组件的AnimatedVisibility进入动画?
用户代码如下:
@Composable fun ContentList() { if (list.size > 0) { Box() { Column { LazyColumn { items() } } } } } else { Emplty() } } @Composable fun Emplty() { var visible by remember { mutableStateOf(false) } LaunchedEffect(Unit) { visible = true } Box() { AnimatedVisibility( visible = visible, enter = scaleIn() + expandVertically(expandFrom = Alignment.Top), ) { Image() } } }
需求:当list.size=0时,能触发Empty组件中AnimatedVisibility的进入动画,且支持在ContentList外部通过代码控制触发。
解决方案
核心思路是将动画触发逻辑与列表状态绑定,通过参数传递的方式把外部的列表状态传入Empty组件,让动画触发时机跟随列表变化,而非仅依赖Empty组件的首次渲染。
步骤1:改造Empty组件,接收外部触发条件
让Empty组件的可见性状态依赖外部传入的列表空状态,每当列表从非空变为空时,重新触发动画:
@Composable fun Empty(listEmpty: Boolean) { var visible by remember { mutableStateOf(false) } // 依赖listEmpty参数,列表状态变化时重新执行 LaunchedEffect(listEmpty) { if (listEmpty) { // 先重置状态,确保重复触发时动画能正常执行 visible = false awaitFrame() // 等待下一帧确保状态更新生效 visible = true } else { visible = false } } Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { AnimatedVisibility( visible = visible, enter = scaleIn() + expandVertically(expandFrom = Alignment.Top), // 可选:添加退出动画,让列表从空变有的过渡更自然 exit = fadeOut() + shrinkVertically() ) { Image( painter = painterResource(id = R.drawable.your_empty_icon), // 替换为你的资源 contentDescription = "Empty list", modifier = Modifier.size(120.dp) ) } } }
步骤2:修改ContentList组件,传递触发参数
在ContentList中,将列表是否为空的状态传递给Empty组件:
@Composable fun ContentList(list: List<Any>) { if (list.isNotEmpty()) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(list) { item -> // 你的列表项内容,示例: Text(text = item.toString(), modifier = Modifier.padding(16.dp)) } } } else { // 传递列表空状态作为动画触发条件 Empty(listEmpty = true) } }
步骤3:外部控制列表状态触发动画
在ContentList的父组件中,只需修改list的状态,当list从非空变为空时,Empty组件会自动触发进入动画:
@Composable fun ParentScreen() { var list by remember { mutableStateOf(listOf("Item 1", "Item 2")) } Column(modifier = Modifier.fillMaxSize()) { Button(onClick = { list = emptyList() }) { Text("清空列表") } ContentList(list = list) } }
内容的提问来源于stack exchange,提问作者k g
相关产品推荐
相关产品推荐

