Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 98f3c0d

Browse files
FIX:修复flutter_page_indicator的bug
1 parent a1cb811 commit 98f3c0d

File tree

5 files changed

+429
-117
lines changed

5 files changed

+429
-117
lines changed

‎ios/Podfile.lock‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ DEPENDENCIES:
3333
- webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
3434

3535
SPEC REPOS:
36-
https://github.com/CocoaPods/Specs.git:
36+
https://github.com/cocoapods/specs.git:
3737
- FMDB
3838

3939
EXTERNAL SOURCES:
@@ -70,4 +70,4 @@ SPEC CHECKSUMS:
7070

7171
PODFILE CHECKSUM: 3dbe063e9c90a5d7c9e4e76e70a821b9e2c1d271
7272

73-
COCOAPODS: 1.8.4
73+
COCOAPODS: 1.7.3
Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
library flutter_page_indicator;
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter/widgets.dart';
5+
6+
class WarmPainter extends BasePainter {
7+
WarmPainter(PageIndicator widget, double page, int index, Paint paint)
8+
: super(widget, page, index, paint);
9+
10+
void draw(Canvas canvas, double space, double size, double radius) {
11+
double progress = page - index;
12+
double distance = size + space;
13+
double start = index * (size + space);
14+
15+
if (progress > 0.5) {
16+
double right = start + size + distance;
17+
//progress=>0.5-1.0
18+
//left:0.0=>distance
19+
20+
double left = index * distance + distance * (progress - 0.5) * 2;
21+
canvas.drawRRect(
22+
new RRect.fromLTRBR(
23+
left, 0.0, right, size, new Radius.circular(radius)),
24+
_paint);
25+
} else {
26+
double right = start + size + distance * progress * 2;
27+
28+
canvas.drawRRect(
29+
new RRect.fromLTRBR(
30+
start, 0.0, right, size, new Radius.circular(radius)),
31+
_paint);
32+
}
33+
}
34+
}
35+
36+
class DropPainter extends BasePainter {
37+
DropPainter(PageIndicator widget, double page, int index, Paint paint)
38+
: super(widget, page, index, paint);
39+
40+
@override
41+
void draw(Canvas canvas, double space, double size, double radius) {
42+
double progress = page - index;
43+
double dropHeight = widget.dropHeight;
44+
double rate = (0.5 - progress).abs() * 2;
45+
double scale = widget.scale;
46+
47+
//lerp(begin, end, progress)
48+
49+
canvas.drawCircle(
50+
new Offset(radius + ((page) * (size + space)),
51+
radius - dropHeight * (1 - rate)),
52+
radius * (scale + rate * (1.0 - scale)),
53+
_paint);
54+
}
55+
}
56+
57+
class NonePainter extends BasePainter {
58+
NonePainter(PageIndicator widget, double page, int index, Paint paint)
59+
: super(widget, page, index, paint);
60+
61+
@override
62+
void draw(Canvas canvas, double space, double size, double radius) {
63+
double progress = page - index;
64+
double secondOffset = index == widget.count - 1
65+
? radius
66+
: radius + ((index + 1) * (size + space));
67+
if (progress > 0.5) {
68+
canvas.drawCircle(new Offset(secondOffset, radius), radius, _paint);
69+
} else {
70+
canvas.drawCircle(new Offset(radius + (index * (size + space)), radius),
71+
radius, _paint);
72+
}
73+
}
74+
}
75+
76+
class SlidePainter extends BasePainter {
77+
SlidePainter(PageIndicator widget, double page, int index, Paint paint)
78+
: super(widget, page, index, paint);
79+
80+
@override
81+
void draw(Canvas canvas, double space, double size, double radius) {
82+
canvas.drawCircle(
83+
new Offset(radius + (page * (size + space)), radius), radius, _paint);
84+
}
85+
}
86+
87+
class ScalePainter extends BasePainter {
88+
ScalePainter(PageIndicator widget, double page, int index, Paint paint)
89+
: super(widget, page, index, paint);
90+
91+
// 连续的两个点,含有最后一个和第一个
92+
@override
93+
bool _shouldSkip(int i) {
94+
if (index == widget.count - 1) {
95+
return i == 0 || i == index;
96+
}
97+
return (i == index || i == index + 1);
98+
}
99+
100+
@override
101+
void paint(Canvas canvas, Size size) {
102+
_paint.color = widget.color;
103+
double space = widget.space;
104+
double size = widget.size;
105+
double radius = size / 2;
106+
for (int i = 0, c = widget.count; i < c; ++i) {
107+
if (_shouldSkip(i)) {
108+
continue;
109+
}
110+
canvas.drawCircle(new Offset(i * (size + space) + radius, radius),
111+
radius * widget.scale, _paint);
112+
}
113+
114+
_paint.color = widget.activeColor;
115+
draw(canvas, space, size, radius);
116+
}
117+
118+
@override
119+
void draw(Canvas canvas, double space, double size, double radius) {
120+
double secondOffset = index == widget.count - 1
121+
? radius
122+
: radius + ((index + 1) * (size + space));
123+
124+
double progress = page - index;
125+
126+
_paint.color = Color.lerp(widget.activeColor, widget.color, progress);
127+
//last
128+
canvas.drawCircle(new Offset(radius + (index * (size + space)), radius),
129+
lerp(radius, radius * widget.scale, progress), _paint);
130+
//first
131+
_paint.color = Color.lerp(widget.color, widget.activeColor, progress);
132+
canvas.drawCircle(new Offset(secondOffset, radius),
133+
lerp(radius * widget.scale, radius, progress), _paint);
134+
}
135+
}
136+
137+
class ColorPainter extends BasePainter {
138+
ColorPainter(PageIndicator widget, double page, int index, Paint paint)
139+
: super(widget, page, index, paint);
140+
141+
// 连续的两个点,含有最后一个和第一个
142+
@override
143+
bool _shouldSkip(int i) {
144+
if (index == widget.count - 1) {
145+
return i == 0 || i == index;
146+
}
147+
return (i == index || i == index + 1);
148+
}
149+
150+
@override
151+
void draw(Canvas canvas, double space, double size, double radius) {
152+
double progress = page - index;
153+
double secondOffset = index == widget.count - 1
154+
? radius
155+
: radius + ((index + 1) * (size + space));
156+
157+
_paint.color = Color.lerp(widget.activeColor, widget.color, progress);
158+
//left
159+
canvas.drawCircle(
160+
new Offset(radius + (index * (size + space)), radius), radius, _paint);
161+
//right
162+
_paint.color = Color.lerp(widget.color, widget.activeColor, progress);
163+
canvas.drawCircle(new Offset(secondOffset, radius), radius, _paint);
164+
}
165+
}
166+
167+
abstract class BasePainter extends CustomPainter {
168+
final PageIndicator widget;
169+
final double page;
170+
final int index;
171+
final Paint _paint;
172+
173+
double lerp(double begin, double end, double progress) {
174+
return begin + (end - begin) * progress;
175+
}
176+
177+
BasePainter(this.widget, this.page, this.index, this._paint);
178+
179+
void draw(Canvas canvas, double space, double size, double radius);
180+
181+
bool _shouldSkip(int index) {
182+
return false;
183+
}
184+
//double secondOffset = index == widget.count-1 ? radius : radius + ((index + 1) * (size + space));
185+
186+
@override
187+
void paint(Canvas canvas, Size size) {
188+
_paint.color = widget.color;
189+
double space = widget.space;
190+
double size = widget.size;
191+
double radius = size / 2;
192+
for (int i = 0, c = widget.count; i < c; ++i) {
193+
if (_shouldSkip(i)) {
194+
continue;
195+
}
196+
canvas.drawCircle(
197+
new Offset(i * (size + space) + radius, radius), radius, _paint);
198+
}
199+
200+
double page = this.page;
201+
if (page < index) {
202+
page = 0.0;
203+
}
204+
_paint.color = widget.activeColor;
205+
draw(canvas, space, size, radius);
206+
}
207+
208+
@override
209+
bool shouldRepaint(BasePainter oldDelegate) {
210+
return oldDelegate.page != page;
211+
}
212+
}
213+
214+
class _PageIndicatorState extends State<PageIndicator> {
215+
int index = 0;
216+
Paint _paint = new Paint();
217+
218+
BasePainter _createPainer() {
219+
switch (widget.layout) {
220+
case PageIndicatorLayout.NONE:
221+
return new NonePainter(
222+
widget,
223+
widget.controller.page ?? widget.initialPage.toDouble(),
224+
index,
225+
_paint);
226+
case PageIndicatorLayout.SLIDE:
227+
return new SlidePainter(
228+
widget,
229+
widget.controller.page ?? widget.initialPage.toDouble(),
230+
index,
231+
_paint);
232+
case PageIndicatorLayout.WARM:
233+
return new WarmPainter(
234+
widget,
235+
widget.controller.page ?? widget.initialPage.toDouble(),
236+
index,
237+
_paint);
238+
case PageIndicatorLayout.COLOR:
239+
return new ColorPainter(
240+
widget,
241+
widget.controller.page ?? widget.initialPage.toDouble(),
242+
index,
243+
_paint);
244+
case PageIndicatorLayout.SCALE:
245+
return new ScalePainter(
246+
widget,
247+
widget.controller.page ?? widget.initialPage.toDouble(),
248+
index,
249+
_paint);
250+
case PageIndicatorLayout.DROP:
251+
return new DropPainter(
252+
widget,
253+
widget.controller.page ?? widget.initialPage.toDouble(),
254+
index,
255+
_paint);
256+
default:
257+
throw new Exception("Not a valid layout");
258+
}
259+
}
260+
261+
@override
262+
Widget build(BuildContext context) {
263+
Widget child = new SizedBox(
264+
width: widget.count * widget.size + (widget.count - 1) * widget.space,
265+
height: widget.size,
266+
child: new CustomPaint(
267+
painter: _createPainer(),
268+
),
269+
);
270+
271+
if (widget.layout == PageIndicatorLayout.SCALE ||
272+
widget.layout == PageIndicatorLayout.COLOR) {
273+
child = new ClipRect(
274+
child: child,
275+
);
276+
}
277+
278+
return new IgnorePointer(
279+
child: child,
280+
);
281+
}
282+
283+
void _onController() {
284+
double page = widget.controller.page ?? 0.0;
285+
index = page.floor();
286+
287+
setState(() {});
288+
}
289+
290+
@override
291+
void initState() {
292+
widget.controller.addListener(_onController);
293+
super.initState();
294+
295+
// Fixed Bug: 初始化时 需要配置 初始化值
296+
double page =
297+
widget.initialPage != null ? widget.initialPage.toDouble() : 0.0;
298+
index = page.floor();
299+
}
300+
301+
@override
302+
void didUpdateWidget(PageIndicator oldWidget) {
303+
if (widget.controller != oldWidget.controller) {
304+
oldWidget.controller.removeListener(_onController);
305+
widget.controller.addListener(_onController);
306+
}
307+
super.didUpdateWidget(oldWidget);
308+
}
309+
310+
@override
311+
void dispose() {
312+
widget.controller.removeListener(_onController);
313+
super.dispose();
314+
}
315+
}
316+
317+
enum PageIndicatorLayout {
318+
NONE,
319+
SLIDE,
320+
WARM,
321+
COLOR,
322+
SCALE,
323+
DROP,
324+
}
325+
326+
class PageIndicator extends StatefulWidget {
327+
/// size of the dots
328+
final double size;
329+
330+
/// space between dots.
331+
final double space;
332+
333+
/// count of dots
334+
final int count;
335+
336+
/// active color
337+
final Color activeColor;
338+
339+
/// normal color
340+
final Color color;
341+
342+
/// layout of the dots,default is [PageIndicatorLayout.SLIDE]
343+
final PageIndicatorLayout layout;
344+
345+
// Only valid when layout==PageIndicatorLayout.scale
346+
final double scale;
347+
348+
// Only valid when layout==PageIndicatorLayout.drop
349+
final double dropHeight;
350+
351+
final PageController controller;
352+
353+
final double activeSize;
354+
355+
/// The page to show when first creating the [PageView].
356+
final int initialPage;
357+
358+
PageIndicator({
359+
Key key,
360+
this.size: 20.0,
361+
this.space: 5.0,
362+
this.count,
363+
this.activeSize: 20.0,
364+
this.controller,
365+
this.color: Colors.white30,
366+
this.layout: PageIndicatorLayout.SLIDE,
367+
this.activeColor: Colors.white,
368+
this.scale: 0.6,
369+
this.dropHeight: 20.0,
370+
this.initialPage = 0,
371+
}) : assert(count != null),
372+
assert(controller != null),
373+
super(key: key);
374+
375+
@override
376+
State<StatefulWidget> createState() {
377+
return new _PageIndicatorState();
378+
}
379+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /