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

能否在Flutter中实现该滑块效果?若可以该如何实现?

实现Flutter堆叠滑动滑块效果

用PageView配合Transform和PageController就能实现你要的堆叠滑动效果,比CarouselSlider更灵活,代码也不复杂,直接上可运行的示例:

import 'package:flutter/material.dart';

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

  @override
  State<StackedSlider> createState() => _StackedSliderState();
}

class _StackedSliderState extends State<StackedSlider> {
  final PageController _pageController = PageController(viewportFraction: 0.8);
  final List<Color> _cardColors = [Colors.blue, Colors.red, Colors.green, Colors.orange];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SizedBox(
          height: 250,
          child: PageView.builder(
            controller: _pageController,
            itemCount: _cardColors.length,
            itemBuilder: (context, index) {
              return AnimatedBuilder(
                animation: _pageController,
                builder: (context, child) {
                  // 计算当前页面与当前index的偏移差
                  double pageOffset = 0;
                  if (_pageController.position.haveDimensions) {
                    pageOffset = _pageController.page! - index;
                  }
                  // 计算缩放比例:当前页面缩放为1,相邻页面缩放为0.8
                  final double scale = 1 - (0.2 * pageOffset.abs());
                  // 计算Y轴位移(可选,让相邻卡片稍微下移,增强堆叠感)
                  final double translateY = (1 - scale) * 10;

                  return Transform(
                    transform: Matrix4.identity()
                      ..scale(scale)
                      ..translate(0, translateY),
                    alignment: Alignment.center,
                    child: Container(
                      margin: const EdgeInsets.symmetric(horizontal: 8),
                      decoration: BoxDecoration(
                        color: _cardColors[index],
                        borderRadius: BorderRadius.circular(16),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withOpacity(0.2),
                            blurRadius: 8,
                            offset: const Offset(0, 4),
                          ),
                        ],
                      ),
                      // 这里可以替换成你自己的卡片内容
                      child: Center(
                        child: Text(
                          '卡片 ${index+1}',
                          style: const TextStyle(
                            color: Colors.white,
                            fontSize: 24,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ),
                  );
                },
              );
            },
          ),
        ),
      ),
    );
  }

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

关键细节说明

  • viewportFraction: 0.8:设置每个页面占屏幕宽度的80%,让左右两侧能露出相邻卡片的边缘
  • AnimatedBuilder:监听PageController的页面偏移变化,实时更新每个卡片的缩放和位置,避免手动管理动画状态
  • 缩放逻辑:通过pageOffset计算当前卡片与滑动位置的偏差,偏差越大缩放比例越小,确保当前选中的卡片最大最突出
  • 可选的translateY:让相邻卡片稍微下移,增强堆叠的层次感,不需要的话可以删掉这部分
  • 调整0.2这个缩放系数可以改变相邻卡片的缩小幅度,数值越大,缩小效果越明显

如果需要自动轮播功能,可以在initState里加个Timer:

@override
void initState() {
  super.initState();
  Timer.periodic(const Duration(seconds: 3), (timer) {
    if (_pageController.page! < _cardColors.length - 1) {
      _pageController.nextPage(
        duration: const Duration(milliseconds: 500),
        curve: Curves.easeInOut,
      );
    } else {
      _pageController.jumpToPage(0);
    }
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 16:39:21