横向分页器堆叠卡片动画实现问题:右滑淡出+放大效果修复
修复HorizontalPager卡片堆叠动画问题
原代码核心问题
- 把
HorizontalPager嵌套在for循环里,生成了多个分页器,直接导致动画逻辑彻底混乱 - 堆叠卡片的布局没有绑定Pager的滑动状态,没法跟着滑动同步变化
修复后的实现代码
@Composable fun StackedPager( modifier: Modifier = Modifier, pagerCount: Int, item: @Composable (Float) -> Unit, button: @Composable (Float) -> Unit ) { val pagerState = rememberPagerState(initialPage = 0) { pagerCount } Box(modifier = modifier) { // 绘制堆叠的下层卡片 for (i in 1 until pagerCount) { val targetPage = pagerState.currentPage val offset = pagerState.currentPageOffsetFraction // 计算动画进度:右滑当前页面时,进度从0到1递增 val progress = if (targetPage == i - 1) offset.coerceIn(0f, 1f) else 0f Column( modifier = Modifier .padding( top = Spaces.xs2 * (pagerCount - i) * (1 - progress), start = Spaces.xs2 * (pagerCount - i) * (1 - progress), end = Spaces.xs2 * (pagerCount - i) * (1 - progress) ) .graphicsLayer { // 下层卡片随滑动逐步放大到原尺寸 scaleX = 0.8f + progress * 0.2f scaleY = 0.8f + progress * 0.2f // 确保下层卡片始终在顶部卡片下方 translationZ = (i - 1).toFloat() * (1 - progress) } ) { item(i.toFloat()) if (i == 1) { button(Spaces.xs2 * (pagerCount - i) * (1 - progress)) } } } // 顶部可滑动的主卡片 HorizontalPager( modifier = Modifier.matchParentSize(), state = pagerState, flingBehavior = PagerDefaults.flingBehavior(state = pagerState) ) { page -> Box( modifier = Modifier .graphicsLayer { val pageOffset = pagerState.currentPageOffsetFraction // 右滑时当前卡片逐步淡出 alpha = 1f - pageOffset.coerceIn(0f, 1f) // 右滑时当前卡片同步缩小 scaleX = 1f - pageOffset.coerceIn(0f, 1f) * 0.2f scaleY = 1f - pageOffset.coerceIn(0f, 1f) * 0.2f translationZ = pagerCount.toFloat() // 保持在最上层 } ) { item(page.toFloat()) } } } }
关键逻辑说明
- 拆分堆叠卡片和主Pager:主Pager只负责顶部当前卡片的滑动交互,下层卡片单独绘制
- 绑定滑动状态:下层卡片根据当前页面和滑动偏移量计算动画参数,右滑时逐步移动到顶部位置并放大
- 衔接动画:顶部卡片右滑时淡出缩小,下层卡片同步放大到位,形成连贯的堆叠切换效果
内容的提问来源于stack exchange,提问作者Rustam
相关产品推荐
相关产品推荐

