flutter_swiper自定义分页指示器

文章介绍了如何在Flutter项目中使用flutter_swiper库自定义分页指示器,特别是如何创建CustomSwiperPaginationBuilder类来实现特定的样式。通过示例代码展示了如何设置不同颜色、大小和布局,并提醒注意autoplay参数的正确使用。
摘要由CSDN通过智能技术生成

flutter_swiper内置了2种分页指示器,一种是SwiperPagination.dots的圆形风格,一种是SwiperPagination.fraction的数字风格,但是这显然不能满足我们的需要,比如下图这种效果:

flutter_swiper提供了这样的能力,但是需要你自己实现

 

你可以看到这文档简直简单,就一个方法就没了,让人摸不到头脑。不慌,你可以看SwiperPagination.dots的实现,就发现其实就一个StatefulWidget,参考源码后,我的代码如下:

新建一个custom_swiper_pagination.dart(flutter2.x+card_swiper 此库是flutter_swiper的空安全版)

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:card_swiper/card_swiper.dart';

/// 自定义页面指示器
class CustomSwiperPaginationBuilder extends SwiperPlugin {
  // 当滚动到此时的颜色
  late Color? activeColor;

  // 默认颜色
  late Color? color;

  // 每个圆点的间距
  final double space;

  // 每个圆点的大小
  final double size;

  // 特殊点的宽度
  final double activeSize;

  final double bottom;

  final AlignmentGeometry? alignment;

  final Key? key;

  CustomSwiperPaginationBuilder(
      {this.color = Colors.grey,
      this.activeColor = Colors.blue,
      this.space = 3.0,
      this.size = 6.0,
      this.activeSize = 20.0,
      this.bottom = 0.0,
      this.alignment = Alignment.center,
      this.key});

  @override
  Widget build(BuildContext context, SwiperPluginConfig config) {
    // 处理边界情况
    if (config.itemCount > 20) {
      log(
        'The itemCount is too big, we suggest use FractionPaginationBuilder '
        'instead of DotSwiperPaginationBuilder in this situation',
      );
    }

    int activeIndex = config.activeIndex;
    // 用于存放小圆点
    List<Widget> list = [];
    for (var i = 0; i < config.itemCount; ++i) {
      if (activeIndex == i) {
        list.add(Container(
            key: Key('pagination_$i'),
            margin: EdgeInsets.all(space),
            child: PhysicalModel(
              color: Colors.transparent,
              borderRadius: BorderRadius.circular(10),
              clipBehavior: Clip.antiAlias,
              child: Container(
                color: activeColor,
                width: activeSize,
                height: size,
              ),
            )));
      } else {
        list.add(Container(
          key: Key('pagination_$i'),
          margin: EdgeInsets.all(space),
          child: ClipOval(
            // 圆角组件
            child: Container(
              color: color,
              width: size,
              height: size,
            ),
          ),
        ));
      }
    }

    return Stack(
      clipBehavior: Clip.none,
      children: [
        Positioned(
            left: 15,
            right: 15,
            bottom: bottom,
            child: Container(
              alignment: alignment,
              color: Colors.transparent,
              child: Row(
                key: key,
                mainAxisSize: MainAxisSize.min,
                mainAxisAlignment: MainAxisAlignment.center,
                children: list,
              ),
            ))
      ],
    );
  }
}

使用此方法:

child: Swiper(
          itemBuilder: (BuildContext context, int index) {
            var swiperItem = swiperList[index];
            return PhysicalModel(
              color: Colors.transparent,
              borderRadius: BorderRadius.circular(10),
              clipBehavior: Clip.antiAlias,
              child: Image.network(
                swiperItem?.img ?? '',
                fit: BoxFit.cover,
              ),
            );
          },
          viewportFraction: 0.85,
          scale: 0.9,
          autoplay: swiperList.isNotEmpty,
          itemCount: swiperList.length,
          pagination: SwiperPagination( // 此处使用自己编写的样式
            builder: CustomSwiperPaginationBuilder(alignment: Alignment.bottomCenter),
          ),
          // control: const SwiperControl(),
        ),

flutter_swiper默认是在图片内部的,因为我需要它显示在外面,因此使用了Stack组件。

注意:autoplay: swiperList.isNotEmpty最好使用isNotEmpty而不是true,否则就可能出现下面这种情况:

 

最终效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值