You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

横向分页器堆叠卡片动画实现问题:右滑淡出+放大效果修复

修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:59:58