-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEasySwiper.dart
175 lines (156 loc) · 4.32 KB
/
EasySwiper.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import './setTimeout.dart';
import './YBorderRadiusBox.dart';
typedef IndexCallback = void Function (int index);
class EasySwiper extends StatefulWidget {
final List<Widget> children;
final bool showDot; // 是否显示小圆点
final Color dotStaticColor; // 小圆点静态颜色
final Color dotActiveColor; // 小圆点高亮颜色
final IndexCallback onChange; // 切换后回调
final bool autoPlay; // 是否自动轮播
final int autoPlayFrequency; // 自动轮播频率(毫秒)
final int autoPlayDuration; // 自动轮播过渡时间(毫秒)
final Curve curve; // 过渡动画效果
final double scale; // 缩放 (0-1)
EasySwiper({
@required this.children,
this.dotActiveColor,
this.dotStaticColor,
this.showDot = true,
this.onChange,
this.autoPlay = true,
this.autoPlayFrequency = 2000,
this.autoPlayDuration = 700,
this.curve = Curves.ease,
this.scale = 1.0
});
@override
_EasySwiper createState () {
return new _EasySwiper();
}
}
class _EasySwiper extends State<EasySwiper> {
PageController _controller;
Timer _timer;
double distence = 0.0;
int currentPage = 0;
bool directionInversion = false; // 是否往回播放
int computedPage = 0;
bool _autoScrolled = false;// 是否已经开始自动轮播,初始化的时候没有数据,导致不触发changed从而自动轮播失效
@override
void initState () {
super.initState();
_controller = new PageController(
initialPage: 0,
keepPage: true,
viewportFraction: widget.scale
);
}
void moveOnce (int toPage) async {
await _controller.animateToPage(
toPage,
duration: Duration(milliseconds: widget.autoPlayDuration),
curve: widget.curve
);
}
void comminAutoPlay () {
if(!widget.autoPlay) return null;
if(directionInversion) {
computedPage = currentPage - 1;
if(computedPage < 0) {
computedPage = 0;
}
} else {
computedPage = currentPage + 1;
if(computedPage > widget.children.length - 1) {
computedPage = 0;
}
}
_timer?.cancel();
_timer = setTimeout((){
moveOnce(computedPage);
}, widget.autoPlayFrequency);
}
void _onChange (int index) async {
if(index==0) {
directionInversion = false;
} else if(index < currentPage || index == widget.children.length -1) {
directionInversion = true;
}
setState(() {
currentPage = index;
});
comminAutoPlay();
if(widget.onChange != null) {
widget.onChange(index);
}
}
@override
Widget build (BuildContext context) {
if(!_autoScrolled && widget.children.length > 0) {
_autoScrolled = true;
comminAutoPlay();
}
return Listener(
onPointerDown: (ev) {
_timer?.cancel();
},
onPointerUp: (ev) {
comminAutoPlay();
},
child: Stack(
children: <Widget>[
PageView(
children: widget.children,
controller: _controller,
onPageChanged: _onChange,
),
widget.showDot ? _Dots(widget, widget.children.length, currentPage) : Container()
],
),
);
}
}
class _Dots extends StatelessWidget {
final int total;
final int index;
final dynamic opt;
_Dots(this.opt, this.total, this.index);
@override
Widget build (BuildContext context) {
List<Widget> children = [];
Color _dotStaticColor;
Color _dotActiveColor;
_dotStaticColor = opt.dotStaticColor ?? Color.fromRGBO(0, 0, 0, 0.2);
_dotActiveColor = opt.dotActiveColor ?? Color.fromRGBO(0, 0, 0, 0.8);
for(int a=0; a<total; a++) {
children.add(Padding(
padding: EdgeInsets.fromLTRB(2, 0, 2, 0),
child: YBorderRadiusBox(
borderRadius: [10,10,10,10],
child: Container(
decoration: BoxDecoration(
color: index == a ? _dotActiveColor :
_dotStaticColor),
width: 10,
height: 2
),
),
));
}
return Positioned(
left: 0,
right: 0,
bottom: 5,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: children,
),
),
);
}
}