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

如何实现类似Louis Vuitton应用的ListView项自定义横向滚动效果

这个效果是卡片居中缩放+纵向偏移视差的横向滚动效果,card_swiper的预设参数无法直接匹配该需求,你可以通过自定义PageView实现,灵活度更高也不会出现依赖兼容问题,具体实现逻辑如下:

实现思路

  • 基础滚动容器使用PageView,设置viewportFraction为0.8,让单页卡片仅占部分宽度,自然露出左右相邻卡片
  • 给PageController添加滚动监听,实时获取当前滚动的页码偏移值
  • 每个卡片构建时,根据自身索引和当前滚动偏移值的差值,动态计算缩放比例和纵向偏移量,差越大的卡片缩放比例越小、纵向偏移越大

示例代码

class LVCardScroll extends StatefulWidget {
  const LVCardScroll({super.key});

  @override
  State<LVCardScroll> createState() => _LVCardScrollState();
}

class _LVCardScrollState extends State<LVCardScroll> {
  final PageController _pageController = PageController(viewportFraction: 0.8);
  double _currentScrollPage = 0;

  @override
  void initState() {
    super.initState();
    // 监听滚动偏移
    _pageController.addListener(() {
      setState(() {
        _currentScrollPage = _pageController.page ?? 0;
      });
    });
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[100],
      body: PageView.builder(
        controller: _pageController,
        // 替换为你的商品实际数量
        itemCount: 15,
        itemBuilder: (context, index) {
          // 计算当前卡片与滚动位置的差值
          double offsetDiff = index - _currentScrollPage;
          // 限制差值范围避免边缘卡片变形
          offsetDiff = offsetDiff.clamp(-1.0, 1.0);
          // 计算缩放值:居中卡片为1,两侧卡片最小缩放至0.8
          double scale = 1 - (offsetDiff.abs() * 0.2);
          // 计算纵向偏移:居中卡片偏移为0,两侧卡片向下偏移20px
          double yOffset = offsetDiff.abs() * 20;

          return Transform.translate(
            offset: Offset(0, yOffset),
            child: Transform.scale(
              scale: scale,
              child: Container(
                margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 40),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: const [
                    BoxShadow(
                      color: Colors.black12,
                      blurRadius: 8,
                      offset: Offset(0, 4),
                    )
                  ]
                ),
                // 替换为你的商品项UI
                child: Center(
                  child: Text("商品 $index", style: const TextStyle(fontSize: 22, fontWeight: FontWeight.w500)),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

你可以根据实际设计需求调整缩放系数、偏移值、viewportFraction参数,即可完全匹配演示效果。

内容的提问来源于stack exchange,提问作者Nabin Dhakal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:27:03