You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			177 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Dart
		
	
| import 'package:flutter/foundation.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| /// Animated progress bar. Behaves like implicitly animated widget.
 | |
| /// Check basic implicit animated Flutter widgets like [AnimatedContainer]
 | |
| /// It animates [value] changes.
 | |
| /// Requires [duration] to set filling duration timer
 | |
| /// [onEnd] callback to trigger additional actions (e.g. another animation)
 | |
| /// at the end of the current animation
 | |
| /// [color] or [gradient] to fill the progress bar. Only one parameter is allowed.
 | |
| /// Optional [backgroundColor], defaults to transparent
 | |
| /// Optional [width] defaults to 200.0
 | |
| /// Optional [height] defaults to 10.0
 | |
| /// Optional [curve] defaults to [Curves.linear]
 | |
| class AnimatedProgressBar extends ImplicitlyAnimatedWidget {
 | |
|   const AnimatedProgressBar({
 | |
|     key,
 | |
|     required duration,
 | |
|     required this.value,
 | |
|     this.width = 200.0,
 | |
|     this.height = 10.0,
 | |
|     this.color,
 | |
|     this.gradient,
 | |
|     this.backgroundColor = Colors.transparent,
 | |
|     curve = Curves.linear,
 | |
|     onEnd,
 | |
|   }) : super(key: key, duration: duration, curve: curve, onEnd: onEnd);
 | |
| 
 | |
|   ///progress bar width
 | |
|   final double width;
 | |
| 
 | |
|   ///progress bar height
 | |
|   final double height;
 | |
| 
 | |
|   ///current progress value
 | |
|   final double? value;
 | |
| 
 | |
|   ///progress bar gradient parameter
 | |
|   final Gradient? gradient;
 | |
| 
 | |
|   ///progress bar color parameter
 | |
|   final Color? color;
 | |
| 
 | |
|   ///progress bar color parameter
 | |
|   final Color backgroundColor;
 | |
| 
 | |
|   @override
 | |
|   AnimatedWidgetBaseState<AnimatedProgressBar> createState() => _AnimatedBarState();
 | |
| }
 | |
| 
 | |
| class _AnimatedBarState extends AnimatedWidgetBaseState<AnimatedProgressBar> {
 | |
|   Tween<double>? _progressValue;
 | |
| 
 | |
|   @override
 | |
|   void forEachTween(TweenVisitor<dynamic> visitor) {
 | |
|     _progressValue = visitor(_progressValue, widget.value, (value) => Tween<double>(begin: value)) as Tween<double>?;
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return ProgressBar(
 | |
|       value: _progressValue?.evaluate(animation),
 | |
|       width: widget.width,
 | |
|       height: widget.height,
 | |
|       gradient: widget.gradient,
 | |
|       color: widget.color,
 | |
|       backgroundColor: widget.backgroundColor,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void debugFillProperties(DiagnosticPropertiesBuilder description) {
 | |
|     super.debugFillProperties(description);
 | |
|     description.add(DiagnosticsProperty<Tween>('progressValue', _progressValue, showName: false, defaultValue: null));
 | |
|   }
 | |
| }
 | |
| 
 | |
| class ProgressBar extends StatelessWidget {
 | |
|   const ProgressBar({
 | |
|     Key? key,
 | |
|     required this.value,
 | |
|     this.width = 200.0,
 | |
|     this.height = 10.0,
 | |
|     this.color,
 | |
|     this.backgroundColor = Colors.transparent,
 | |
|     this.gradient,
 | |
|   })  : assert(
 | |
|           gradient == null || color == null,
 | |
|           'Cannot provide both a color and a gradient',
 | |
|         ),
 | |
|         assert(
 | |
|           gradient != null || color != null,
 | |
|           'Need to provide color or gradient',
 | |
|         ),
 | |
|         super(key: key);
 | |
| 
 | |
|   ///progress bar width
 | |
|   final double width;
 | |
| 
 | |
|   ///progress bar height
 | |
|   final double height;
 | |
| 
 | |
|   ///current progress value
 | |
|   final double? value;
 | |
| 
 | |
|   ///progress bar gradient parameter
 | |
|   final Gradient? gradient;
 | |
| 
 | |
|   ///progress bar color parameter
 | |
|   final Color? color;
 | |
| 
 | |
|   ///progress bar color parameter
 | |
|   final Color backgroundColor;
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     return CustomPaint(
 | |
|       size: Size(width, height),
 | |
|       foregroundPainter: ProgressPainter(
 | |
|         value: value!,
 | |
|         color: color,
 | |
|         gradient: gradient,
 | |
|       ),
 | |
|       painter: BackgroundPainter(
 | |
|         backgroundColor: backgroundColor,
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| class BackgroundPainter extends CustomPainter {
 | |
|   const BackgroundPainter({required this.backgroundColor});
 | |
| 
 | |
|   ///progress bar backgroundColor
 | |
|   final Color backgroundColor;
 | |
| 
 | |
|   @override
 | |
|   void paint(Canvas canvas, Size size) {
 | |
|     Paint paint = Paint()..color = backgroundColor;
 | |
|     canvas.drawRRect(RRect.fromRectAndRadius(Offset.zero & size, Radius.circular(6)), paint);
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   bool shouldRepaint(covariant BackgroundPainter oldDelegate) => false;
 | |
| }
 | |
| 
 | |
| class ProgressPainter extends CustomPainter {
 | |
|   const ProgressPainter({required this.value, this.gradient, this.color});
 | |
| 
 | |
|   ///current progress bar value
 | |
|   final double value;
 | |
| 
 | |
|   ///progress bar gradient infill
 | |
|   final Gradient? gradient;
 | |
| 
 | |
|   ///progress bar gradient color
 | |
|   final Color? color;
 | |
| 
 | |
|   @override
 | |
|   void paint(Canvas canvas, Size size) {
 | |
|     Paint paint = Paint();
 | |
|     if (gradient != null) {
 | |
|       paint.shader = gradient?.createShader(Offset.zero & size);
 | |
|     }
 | |
|     if (color != null) {
 | |
|       paint.color = color!;
 | |
|     }
 | |
|     canvas.clipRRect(RRect.fromRectAndRadius(Offset.zero & size, Radius.circular(6)));
 | |
|     canvas.drawRRect(RRect.fromRectAndRadius(Rect.fromLTRB(0, 0, size.width * value, size.height), Radius.circular(6)), paint);
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   bool shouldRepaint(covariant ProgressPainter oldDelegate) {
 | |
|     return value != oldDelegate.value;
 | |
|   }
 | |
| }
 |