Jetpack Compose实现图片半折叠:滚动时停在原尺寸50%
在Jetpack Compose中实现图片半折叠效果
需求:向下滚动列表时,顶部图片随滚动折叠,但不会完全收起,例如折叠至原尺寸的50%后停止。当前实现会导致图片完全折叠,需要调整逻辑限制折叠范围。
修改后的实现代码
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ExampleAppTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { CollapseImage() } } } } } @Composable fun CollapseImage() { val lazyListState = rememberLazyListState() // 记录图片的原始高度 var imageHeight by remember { mutableStateOf(0f) } // 定义图片保留比例(此处为50%,即最多折叠50%) val keepRatio = 0.5f // 计算最大允许的折叠偏移量:原始高度 * (1 - 保留比例) val maxCollapseOffset by remember(imageHeight) { derivedStateOf { imageHeight * (1 - keepRatio) } } val firstItemTranslationY by remember { derivedStateOf { if (lazyListState.firstVisibleItemIndex == 0 && lazyListState.layoutInfo.visibleItemsInfo.isNotEmpty()) { // 取滚动偏移量和最大折叠偏移量的较小值,限制折叠范围 min(lazyListState.firstVisibleItemScrollOffset.toFloat(), maxCollapseOffset) } else { 0f } } } LazyColumn(state = lazyListState) { item { Image( painter = painterResource(id = R.drawable.ic_launcher_foreground), contentDescription = null, modifier = Modifier .fillParentMaxWidth() .onSizeChanged { size -> // 获取图片实际高度 imageHeight = size.height.toFloat() } .graphicsLayer { // 限制translationY不超过最大偏移量,确保图片保留指定比例 translationY = -firstItemTranslationY }, contentScale = ContentScale.Crop, ) } items(100) { item -> Text(text = item.toString(), modifier = Modifier.padding(16.dp)) } } }
关键修改点
- 获取图片原始高度:通过
onSizeChanged回调捕获图片的实际渲染高度,作为计算折叠上限的基础。 - 设置折叠阈值:根据需求的保留比例计算
maxCollapseOffset,这是图片允许向上折叠的最大距离。 - 限制滚动偏移:在计算
firstItemTranslationY时,取滚动偏移量和最大折叠偏移量的最小值,确保图片折叠到指定比例后不再继续收起。
注:如果图片折叠方向不符合预期,可调整translationY的正负值来修改图片移动方向。
内容的提问来源于stack exchange,提问作者Zirpula
相关产品推荐
相关产品推荐

