Jetpack Compose中监听Lazy Column内青色项的可见进度
监听LazyColumn项的可见进度并实现文本移除动画
完全可以实现这个需求,核心是借助LazyListState提供的布局信息,实时计算青色背景项的可见高度占总高度的比例,再用这个比例控制文本的动画效果。
实现步骤
- 计算可见比例:通过
LazyListState.layoutInfo获取目标项的布局参数,对比它与LazyColumn视口的位置关系,算出可见高度占自身总高度的比例(范围0-1)。 - 实时更新进度:用
LaunchedEffect监听滚动状态变化,每次滚动时重新计算可见比例并更新状态。 - 绑定动画效果:将比例值应用到文本的透明度、偏移量等属性,实现滚动时的移除动画。
完整代码示例
val scaffoldState = rememberScaffoldState() val lazyListState = rememberLazyListState() // 保存可见进度,1代表完全可见,0代表完全不可见 val visibleProgress by remember { mutableStateOf(1f) } // 给目标项设置唯一key,方便定位 val targetItemKey = "profile-header" LaunchedEffect(lazyListState) { snapshotFlow { lazyListState.layoutInfo } .collect { layoutInfo -> // 找到目标项的布局信息 val targetItem = layoutInfo.visibleItemsInfo.find { it.key == targetItemKey } targetItem?.let { item -> val itemTotalHeight = item.size val viewportHeight = layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset // 计算可见部分高度 val hiddenTop = maxOf(0, layoutInfo.viewportStartOffset - item.offset) val hiddenBottom = maxOf(0, item.offset + itemTotalHeight - layoutInfo.viewportEndOffset) val visibleHeight = itemTotalHeight - hiddenTop - hiddenBottom // 更新进度,确保值在0-1之间 visibleProgress = (visibleHeight.toFloat() / itemTotalHeight).coerceIn(0f, 1f) } ?: run { // 目标项完全不可见时进度设为0 visibleProgress = 0f } } } Scaffold( scaffoldState = scaffoldState, topBar = { TopAppBar( title = { Text(fontSize = 30.sp, text = "Account", color = Color.White) }, backgroundColor = Color.Black ) }, content = { LazyColumn(state = lazyListState) { item(key = targetItemKey) { Row( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .background(color = Color.Cyan) ) { Text( text = "First Last", fontSize = 20.sp, color = Color.White, modifier = Modifier .padding(20.dp) // 用进度驱动动画:透明度从1到0,同时向左偏移 .alpha(visibleProgress) .offset(x = (1 - visibleProgress) * (-30).dp) ) } } items(list) { Row( Modifier .fillMaxWidth() .wrapContentHeight() .padding(start = 20.dp, top = 10.dp, bottom = 10.dp) ) { Text(it) } } } } )
关键说明
- 目标项定位:给青色项设置唯一
key,能在滚动时快速从可见项列表中找到它。 - 可见高度计算:通过对比项的偏移量与视口的起止偏移,算出实际可见高度,再除以总高度得到比例。
- 动画自定义:示例用了透明度和水平偏移动画,你也可以根据需求改成缩放、淡出等其他效果。
内容的提问来源于stack exchange,提问作者Svilen Rusev
相关产品推荐
相关产品推荐

