A support interval, multicolor, rounded corner, horizontal, vertical progress bar
The characteristics of
- Supports horizontal and vertical directions
- Supports progress bar interval colors
- Support multicolor Settings
- Initial rounded corners are supported
use
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [10.29.18.27.16.15.24.3.20.10].map<Widget>((i) {
return Padding(
padding: EdgeInsets.only(right: 10),
child: IntervalProgressBar(
direction: IntervalProgressDirection.vertical,
max: 30,
progress: i,
intervalSize: 2,
size: Size(12.200),
highlightColor: Colors.red,
defaultColor: Colors.grey,
intervalColor: Colors.transparent,
intervalHighlightColor: Colors.transparent,
reverse: true,
radius: 0));
}).toList())
)
Copy the code
attribute
attribute | type | instructions |
---|---|---|
direction | enum |
The direction of the progress bar, horizontal or vertical |
max | int |
Number of progress blocks |
progress | int |
Highlight the number of progress blocks |
intervalSize | int |
The size of the interval between progress blocks. When horizontal, it represents width; When vertical, it means height |
size | Size |
Control size |
highlightColor | Color |
Highlight the color of the progress block |
defaultColor | Color |
The default color of the progress block |
intervalColor | Color |
The default color of the interval block |
intervalHighlightColor | Color |
Highlight the color of the spacing blocks between progress blocks |
reverse | bool |
Whether to fill it in reverse order |
radius | int |
Rounded corner of starting block |
implementation
Abstract base class
- Calculates public properties for horizontal and vertical progress bars
- Of calling a subclass
paintBlock
Execute specificdraw
operation
abstract class IntervalProgressPainter extends CustomPainter {
final int max;
final int progress;
final int intervalSize;
final Color highlightColor;
final Color defaultColor;
final Color intervalColor;
final Color intervalHighlightColor;
final double radius;
final bool reverse;
finalPaint _paint = Paint() .. style = PaintingStyle.fill .. isAntiAlias =true;
Rect bound;
IntervalProgressPainter(
this.max,
this.progress,
this.intervalSize,
this.highlightColor,
this.defaultColor,
this.intervalColor,
this.intervalHighlightColor,
this.radius,
this.reverse);
@override
@mustCallSuper
void paint(Canvas canvas, Size size) {
if (progress > max) {
throw Exception("progress must <= max");
}
bound = Offset.zero & size;
Size blockSize = calBlockSize();
for (int i = 0; i < max; i++) {
/// Call the subclass to perform the drawingpaintBlock(canvas, i, blockSize); }}@override
bool shouldRepaint(CustomPainter oldDelegate) {
final old = oldDelegate as IntervalProgressPainter;
returnold.max ! = max || old.progress ! = progress || old.intervalSize ! = intervalSize || old.intervalColor ! = intervalColor || old.defaultColor ! = defaultColor || old.highlightColor ! = highlightColor || old.intervalHighlightColor ! = intervalHighlightColor || old.radius ! = radius; }bool highlightBlock(int index) =>
reverse ? index >= (max - progress) : index < progress;
bool highlightInterval(int index) =>
reverse ? index >= (max - progress - 1) : index < progress - 1;
void paintBlock(Canvas canvas, int blockIndex, Size blockSize);
Size calBlockSize();
bool shouldDrawStartRadius(int index) => index == 0 && radius > 0;
bool shouldDrawEndRadius(int index) => index == max - 1 && radius > 0;
bool shouldDrawInterval(intindex) => index ! = max -1&& (intervalColor ! = IntervalProgressBar.TRANSPARENT || intervalHighlightColor ! = IntervalProgressBar.TRANSPARENT); }Copy the code
Horizontal progress bar
- Calculate the size of each progress block
@override
Size calBlockSize() =>
Size(((bound.width - intervalSize * (max - 1)) / max), bound.height);
Copy the code
- Draw each block
@override
void paintBlock(Canvas canvas, int i, Size blockSize) {
/// blockSize: return value of calBlockSize
/// I: block index
final blockWidth = blockSize.width;
final highlight = highlightBlock(i);
final dx = (blockWidth + intervalSize) * i;
Rect rect = Rect.fromLTRB(0.0, blockWidth, bound.height);
_paint.color = highlight ? highlightColor : defaultColor;
canvas.save();
/// Canvas moves dx: progress block width + interval block width
canvas.translate(dx, 0);
/// Draw the initial rounded corner
if (shouldDrawStartRadius(i)) {
rect = _drawLeftRound(canvas, rect);
}
/// Draw the rounded corners at the end
if (shouldDrawEndRadius(i)) {
rect = _drawRightRound(canvas, rect);
}
/ / / drawing block
canvas.drawRect(rect, _paint);
/// Draw spacer blocks
if (shouldDrawInterval(i)) {
_paint.color =
highlightInterval(i) ? intervalHighlightColor : intervalColor;
canvas.drawRect(
Rect.fromLTRB(
blockWidth,
0,
blockWidth + intervalSize,
bound.height,
),
_paint);
}
canvas.restore();
}
Copy the code
- Draws a rectangle with rounded corners on one side and unrounded corners on the other
void _drawRadius(Canvas canvas, Rect rect, Rect clipRect) {
final roundRect = RRect.fromLTRBR(
rect.left, rect.top, rect.right, rect.bottom, Radius.circular(radius));
final path = Path()..addRRect(roundRect);
canvas.save();
canvas.clipRect(clipRect, clipOp: ClipOp.difference);
canvas.drawPath(path, _paint);
canvas.restore();
}
}
Copy the code
The vertical progress bar is similar, please see the source code
Github.com/stefanJi/In…