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

如何在Flutter中实现带宽幅选中指示器的滑动引导页?

实现选中项宽度更大的轮播/引导页指示器

方案1:自定义指示器组件

直接编写自定义Indicator组件,通过控制选中项的宽度实现目标样式,灵活性更高,不受现有包限制:

class CustomIndicator extends StatelessWidget {
  final int currentIndex;
  final int itemCount;
  final double activeWidth;
  final double inactiveWidth;
  final double height;
  final Color activeColor;
  final Color inactiveColor;
  final double borderRadius;

  const CustomIndicator({
    super.key,
    required this.currentIndex,
    required this.itemCount,
    this.activeWidth = 32,
    this.inactiveWidth = 12,
    this.height = 6,
    this.activeColor = Colors.blue,
    this.inactiveColor = Colors.grey,
    this.borderRadius = 3,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(itemCount, (index) {
        return AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          margin: const EdgeInsets.symmetric(horizontal: 4),
          width: index == currentIndex ? activeWidth : inactiveWidth,
          height: height,
          decoration: BoxDecoration(
            color: index == currentIndex ? activeColor : inactiveColor,
            borderRadius: BorderRadius.circular(borderRadius),
          ),
        );
      }),
    );
  }
}

方案2:集成到flutter_onboarding_slider

flutter_onboarding_slider支持自定义指示器,将上述组件传入indicator参数即可:

FlutterOnboardingSlider(
  finishButtonText: '完成',
  onFinish: () {
    // 引导完成逻辑
  },
  pages: [
    OnboardingPage(
      title: '欢迎页1',
      body: '这是第一个引导页面',
      image: const Icon(Icons.ac_unit),
    ),
    OnboardingPage(
      title: '欢迎页2',
      body: '这是第二个引导页面',
      image: const Icon(Icons.access_alarm),
    ),
  ],
  indicator: (context, index, pageCount) => CustomIndicator(
    currentIndex: index,
    itemCount: pageCount,
    activeWidth: 30,
    inactiveWidth: 10,
  ),
);

方案3:集成到轮播组件(如carousel_slider)

搭配carousel_slider使用时,监听页面索引变化来更新指示器状态:

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

  @override
  State<CarouselWithCustomIndicator> createState() => _CarouselWithCustomIndicatorState();
}

class _CarouselWithCustomIndicatorState extends State<CarouselWithCustomIndicator> {
  int _currentIndex = 0;
  final List<String> _carouselItems = [
    // 替换为你的轮播内容
    '轮播项1',
    '轮播项2',
    '轮播项3',
  ];

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        CarouselSlider(
          options: CarouselOptions(
            onPageChanged: (index, reason) {
              setState(() {
                _currentIndex = index;
              });
            },
          ),
          items: _carouselItems.map((item) {
            return Builder(
              builder: (context) => Container(
                alignment: Alignment.center,
                child: Text(item),
              ),
            );
          }).toList(),
        ),
        const SizedBox(height: 16),
        CustomIndicator(
          currentIndex: _currentIndex,
          itemCount: _carouselItems.length,
        ),
      ],
    );
  }
}

你可以根据需求调整自定义指示器的宽度、颜色、动画时长等参数,完全匹配图中的样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:45:37