1.网上看了很多Swiper自定义指示器,都是复制源码进行修改来做的。源码里面的指示器都是绘制的,很难达到自己的需求。自己尝试根据分析源码来实现自定义的指示器
- Swiper指示器 作者支持自定义。给我们预留好了api接口
///The swiper pagination plugin
final SwiperPlugin pagination;
const SwiperPagination(
{this.alignment,
this.key,
this.margin: const EdgeInsets.all(10.0),
this.builder: SwiperPagination.dots});
我们实现 pagination最终得到以下方法
//这是自带的指示器
pagination: new SwiperPagination(
builder: DotSwiperPaginationBuilder(
size: 8,
activeSize: 8,
color: Colours.hexColor(0x333333, alpha: 0.3),
activeColor: Colours.hexColor(0x333333, alpha: 1),
),
)),
//我们自己实现的
pagination:!isIndicator ?null: new SwiperPagination(
margin: EdgeInsets.all(0),
alignment: Alignment.bottomCenter,
builder: new SwiperCustomPagination(
builder: (BuildContext context, SwiperPluginConfig config) {
return list.length==0?Container(): new PageIndicator(
count: list.length,
config: config,
);
}))),
参考DotSwiperPaginationBuilder 的实现方式,大致就是,监听Swiper的滚动拿到当前滚动页的索引来刷新页面 ,
PageIndicator 通过PageIndicator 这个类我们可以看到
@override
void initState() {
widget.controller.addListener(_onController);
super.initState();
}
@override
void didUpdateWidget(PageIndicator oldWidget) {
if(widget.controller != oldWidget.controller){
oldWidget.controller.removeListener(_onController);
widget.controller.addListener(_onController);
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
widget.controller.removeListener(_onController);
super.dispose();
}
void _onController() {
double page = widget.controller.page ?? 0.0;
index = page.floor();
setState(() {});
}
基于以上分析发下的自定义源码
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
class PageIndicator extends StatefulWidget {
final SwiperPluginConfig config;
final int count;
const PageIndicator({Key key,this.config,this.count}) : super(key: key);
@override
_PageIndicatorState createState() => _PageIndicatorState();
}
class _PageIndicatorState extends State {
int index = 0;
@override
void initState() {
// TODO: implement initState
widget.config.pageController.addListener(_onController);
super.initState();
}
void didUpdateWidget(PageIndicator oldWidget) {
if(widget.config.pageController != oldWidget.config.pageController){
oldWidget.config.pageController.removeListener(_onController);
widget.config.pageController.addListener(_onController);
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
widget.config.pageController.removeListener(_onController);
super.dispose();
}
void _onController() {
double page = widget.config.pageController.page ?? 0.0;
index = page.floor();
print(index);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Container(
height: 31,
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 5),
decoration: BoxDecoration(
// color: Colors.black38,
borderRadius: BorderRadius.circular(12),
gradient: LinearGradient( //渐变位置
begin: Alignment.topCenter, //右上
end: Alignment.bottomCenter, //左下
stops: [0.1, 1.1], //[渐变起始点, 渐变结束点]
//渐变颜色[始点颜色, 结束颜色]
colors: [Colors.transparent, Colors.black26]
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:_rowWidgets()
),
);
}
List _rowWidgets(){
List list = [];
for (int x = 0 ; x < widget.count; x ++){
list.add(x == index ? _linePointWidget() : _pointWidget()
);
list.add(SizedBox(width: 5,),
);
}
return list;
}
Widget _linePointWidget(){
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
width: 7,
height: 4,
);
}
Widget _pointWidget(){
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2)
),
width: 4,
height: 4,
);
}
}
使用
pagination: new SwiperPagination(
margin: EdgeInsets.all(0),
alignment: Alignment.bottomCenter,
builder: new SwiperCustomPagination(
builder: (BuildContext context, SwiperPluginConfig config) {
return list.length==0?Container(): new PageIndicator(
count: list.length,
config: config,
);
}))),