Skip to content

Commit c2fe740

Browse files
committed
gf-progress indicator in process
1 parent ede981e commit c2fe740

1 file changed

Lines changed: 321 additions & 3 deletions

File tree

Lines changed: 321 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,332 @@
1+
//import 'package:flutter/material.dart';
2+
//import 'package:getflutter/getflutter.dart';
3+
//
4+
//class GFProgressIndicator extends StatefulWidget {
5+
// @override
6+
// _GFProgressIndicatorState createState() => _GFProgressIndicatorState();
7+
//}
8+
//
9+
//class _GFProgressIndicatorState extends State<GFProgressIndicator> {
10+
// @override
11+
// Widget build(BuildContext context) {
12+
// return Container();
13+
// }
14+
//}
15+
16+
117
import 'package:flutter/material.dart';
2-
import 'package:getflutter/getflutter.dart';
18+
19+
enum LinearStrokeCap { butt, round, roundAll }
320

421
class GFProgressIndicator extends StatefulWidget {
22+
///Percent value between 0.0 and 1.0
23+
final double percent;
24+
final double width;
25+
26+
///Height of the line
27+
final double lineHeight;
28+
29+
30+
///First color applied to the complete line
31+
final Color backgroundColor;
32+
33+
Color get progressColor => _progressColor;
34+
35+
Color _progressColor;
36+
37+
///true if you want the Line to have animation
38+
final bool animation;
39+
40+
///duration of the animation in milliseconds, It only applies if animation attribute is true
41+
final int animationDuration;
42+
43+
///widget at the left of the Line
44+
final Widget leading;
45+
46+
///widget at the right of the Line
47+
final Widget trailing;
48+
49+
///widget inside the Line
50+
final Widget center;
51+
52+
///The kind of finish to place on the end of lines drawn, values supported: butt, round, roundAll
53+
final LinearStrokeCap linearStrokeCap;
54+
55+
///alignment of the Row (leading-widget-center-trailing)
56+
final MainAxisAlignment alignment;
57+
58+
///padding to the GFProgressIndicator
59+
final EdgeInsets padding;
60+
61+
/// set true if you want to animate the linear from the last percent value you set
62+
final bool animateFromLastPercent;
63+
64+
/// If present, this will make the progress bar colored by this gradient.
65+
///
66+
/// This will override [progressColor]. It is an error to provide both.
67+
final LinearGradient linearGradient;
68+
69+
/// set false if you don't want to preserve the state of the widget
70+
final bool addAutomaticKeepAlive;
71+
72+
/// set true if you want to animate the linear from the right to left (RTL)
73+
final bool isRTL;
74+
75+
/// Creates a mask filter that takes the progress shape being drawn and blurs it.
76+
final MaskFilter maskFilter;
77+
78+
/// Set true if you want to display only part of [linearGradient] based on percent value
79+
/// (ie. create 'VU effect'). If no [linearGradient] is specified this option is ignored.
80+
final bool clipLinearGradient;
81+
82+
GFProgressIndicator({
83+
Key key,
84+
this.percent = 0.0,
85+
this.lineHeight = 5.0,
86+
this.width,
87+
this.backgroundColor = const Color(0xFFB8C7CB),
88+
this.linearGradient,
89+
Color progressColor,
90+
this.animation = false,
91+
this.animationDuration = 500,
92+
this.animateFromLastPercent = false,
93+
this.isRTL = false,
94+
this.leading,
95+
this.trailing,
96+
this.center,
97+
this.addAutomaticKeepAlive = true,
98+
this.linearStrokeCap,
99+
this.padding = const EdgeInsets.symmetric(horizontal: 10.0),
100+
this.alignment = MainAxisAlignment.start,
101+
this.maskFilter,
102+
this.clipLinearGradient = false,
103+
}) : super(key: key) {
104+
if (linearGradient != null && progressColor != null) {
105+
throw ArgumentError(
106+
'Cannot provide both linearGradient and progressColor');
107+
}
108+
_progressColor = progressColor ?? Colors.red;
109+
110+
if (percent < 0.0 || percent > 1.0) {
111+
throw new Exception("Percent value must be a double between 0.0 and 1.0");
112+
}
113+
}
114+
5115
@override
6116
_GFProgressIndicatorState createState() => _GFProgressIndicatorState();
7117
}
8118

9-
class _GFProgressIndicatorState extends State<GFProgressIndicator> {
119+
class _GFProgressIndicatorState extends State<GFProgressIndicator>
120+
with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
121+
AnimationController _animationController;
122+
Animation _animation;
123+
double _percent = 0.0;
124+
125+
@override
126+
void dispose() {
127+
if (_animationController != null) {
128+
_animationController.dispose();
129+
}
130+
super.dispose();
131+
}
132+
133+
@override
134+
void initState() {
135+
if (widget.animation) {
136+
_animationController = new AnimationController(
137+
vsync: this,
138+
duration: Duration(milliseconds: widget.animationDuration));
139+
_animation =
140+
Tween(begin: 0.0, end: widget.percent).animate(_animationController)
141+
..addListener(() {
142+
setState(() {
143+
_percent = _animation.value;
144+
});
145+
});
146+
_animationController.forward();
147+
} else {
148+
_updateProgress();
149+
}
150+
super.initState();
151+
}
152+
153+
@override
154+
void didUpdateWidget(GFProgressIndicator oldWidget) {
155+
super.didUpdateWidget(oldWidget);
156+
if (oldWidget.percent != widget.percent) {
157+
if (_animationController != null) {
158+
_animationController.duration =
159+
Duration(milliseconds: widget.animationDuration);
160+
_animation = Tween(
161+
begin: widget.animateFromLastPercent ? oldWidget.percent : 0.0,
162+
end: widget.percent)
163+
.animate(_animationController);
164+
_animationController.forward(from: 0.0);
165+
} else {
166+
_updateProgress();
167+
}
168+
}
169+
}
170+
171+
_updateProgress() {
172+
setState(() {
173+
_percent = widget.percent;
174+
});
175+
}
176+
10177
@override
11178
Widget build(BuildContext context) {
12-
return Container();
179+
super.build(context);
180+
var items = List<Widget>();
181+
if (widget.leading != null) {
182+
items.add(widget.leading);
183+
}
184+
final hasSetWidth = widget.width != null;
185+
var containerWidget = Container(
186+
width: hasSetWidth ? widget.width : double.infinity,
187+
height: widget.lineHeight,
188+
padding: widget.padding,
189+
child: CustomPaint(
190+
painter: LinearPainter(
191+
isRTL: widget.isRTL,
192+
progress: _percent,
193+
center: widget.center,
194+
progressColor: widget.progressColor,
195+
linearGradient: widget.linearGradient,
196+
backgroundColor: widget.backgroundColor,
197+
linearStrokeCap: widget.linearStrokeCap,
198+
lineWidth: widget.lineHeight,
199+
maskFilter: widget.maskFilter,
200+
clipLinearGradient: widget.clipLinearGradient,
201+
),
202+
child: (widget.center != null)
203+
? Center(child: widget.center)
204+
: Container(),
205+
),
206+
);
207+
208+
if (hasSetWidth) {
209+
items.add(containerWidget);
210+
} else {
211+
items.add(Expanded(
212+
child: containerWidget,
213+
));
214+
}
215+
if (widget.trailing != null) {
216+
items.add(widget.trailing);
217+
}
218+
219+
return Material(
220+
color: Colors.transparent,
221+
child: new Container(
222+
child: Row(
223+
mainAxisAlignment: widget.alignment,
224+
crossAxisAlignment: CrossAxisAlignment.center,
225+
children: items,
226+
)),
227+
);
13228
}
229+
230+
@override
231+
bool get wantKeepAlive => widget.addAutomaticKeepAlive;
14232
}
233+
234+
class LinearPainter extends CustomPainter {
235+
final Paint _paintBackground = new Paint();
236+
final Paint _paintLine = new Paint();
237+
final lineWidth;
238+
final progress;
239+
final center;
240+
final isRTL;
241+
final Color progressColor;
242+
final Color backgroundColor;
243+
final LinearStrokeCap linearStrokeCap;
244+
final LinearGradient linearGradient;
245+
final MaskFilter maskFilter;
246+
final bool clipLinearGradient;
247+
248+
LinearPainter({
249+
this.lineWidth,
250+
this.progress,
251+
this.center,
252+
this.isRTL,
253+
this.progressColor,
254+
this.backgroundColor,
255+
this.linearStrokeCap = LinearStrokeCap.butt,
256+
this.linearGradient,
257+
this.maskFilter,
258+
this.clipLinearGradient,
259+
}) {
260+
_paintBackground.color = backgroundColor;
261+
_paintBackground.style = PaintingStyle.stroke;
262+
_paintBackground.strokeWidth = lineWidth;
263+
264+
_paintLine.color = progress.toString() == "0.0"
265+
? progressColor.withOpacity(0.0)
266+
: progressColor;
267+
_paintLine.style = PaintingStyle.stroke;
268+
_paintLine.strokeWidth = lineWidth;
269+
270+
if (linearStrokeCap == LinearStrokeCap.round) {
271+
_paintLine.strokeCap = StrokeCap.round;
272+
} else if (linearStrokeCap == LinearStrokeCap.butt) {
273+
_paintLine.strokeCap = StrokeCap.butt;
274+
} else {
275+
_paintLine.strokeCap = StrokeCap.round;
276+
_paintBackground.strokeCap = StrokeCap.round;
277+
}
278+
}
279+
280+
@override
281+
void paint(Canvas canvas, Size size) {
282+
final start = Offset(0.0, size.height / 2);
283+
final end = Offset(size.width, size.height / 2);
284+
canvas.drawLine(start, end, _paintBackground);
285+
286+
if (maskFilter != null) {
287+
_paintLine.maskFilter = maskFilter;
288+
}
289+
290+
if (isRTL) {
291+
final xProgress = size.width - size.width * progress;
292+
if (linearGradient != null) {
293+
_paintLine.shader = _createGradientShaderRightToLeft(size, xProgress);
294+
}
295+
canvas.drawLine(end, Offset(xProgress, size.height / 2), _paintLine);
296+
} else {
297+
final xProgress = size.width * progress;
298+
if (linearGradient != null) {
299+
_paintLine.shader = _createGradientShaderLeftToRight(size, xProgress);
300+
}
301+
canvas.drawLine(start, Offset(xProgress, size.height / 2), _paintLine);
302+
}
303+
}
304+
305+
Shader _createGradientShaderRightToLeft(Size size, double xProgress) {
306+
Offset shaderEndPoint =
307+
clipLinearGradient ? Offset.zero : Offset(xProgress, size.height);
308+
return linearGradient.createShader(
309+
Rect.fromPoints(
310+
Offset(size.width, size.height),
311+
shaderEndPoint,
312+
),
313+
);
314+
}
315+
316+
Shader _createGradientShaderLeftToRight(Size size, double xProgress) {
317+
Offset shaderEndPoint = clipLinearGradient
318+
? Offset(size.width, size.height)
319+
: Offset(xProgress, size.height);
320+
return linearGradient.createShader(
321+
Rect.fromPoints(
322+
Offset.zero,
323+
shaderEndPoint,
324+
),
325+
);
326+
}
327+
328+
@override
329+
bool shouldRepaint(CustomPainter oldDelegate) {
330+
return true;
331+
}
332+
}

0 commit comments

Comments
 (0)