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
|
11 months ago
|
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;
|
||
|
|
}
|
||
|
|
}
|