Reputation: 421
Hello Flutter Community,
i want to create this custom CircularProgressIndicator:
For the text I built a stack:
Stack(
children: [
Container(
height: 75.0,
width: 75.0,
child: CircularProgressIndicator(
strokeWidth: 6.0,
backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
valueColor: AlwaysStoppedAnimation<Color>(
Color.fromRGBO(252, 90, 73, 1.0)),
value: 0.4,
),
),
Positioned(
child: Container(
height: 75.0,
width: 75.0,
child: Center(
child: Text("2 of 6"),
),
),
),
],
),
I thought of drawing six lines with +60° (amount-of-steps/360°) rotation from the center to the end, but I don't know how to do so.
Is there an elegant way of achieving this?
Cheers from germany
Edit (1): I have found a solution, but i'm not happy with it:
Stack(
children: [
Container(
height: 75.0,
width: 75.0,
child: CircularProgressIndicator(
strokeWidth: 6.0,
backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
valueColor: AlwaysStoppedAnimation<Color>(
Color.fromRGBO(252, 90, 73, 1.0)),
value: 2/6,
),
),
Positioned(
height: 75.0,
width: 75.0,
child: Center(
child: CustomPaint(
painter: DrawRadialLines(
amount: 6,
thickness: 4,
length: 75,
color: Colors.white),
),
),
),
Positioned(
child: Container(
height: 75.0,
width: 75.0,
child: Center(
child: Text("2 of 6"),
),
),
),
],
),
And this Class DrawRadialLines:
class DrawRadialLines extends CustomPainter {
Paint _paint;
final double thickness;
final double amount;
final double length;
final Color color;
DrawRadialLines({this.thickness, this.amount, this.length, this.color}) {
_paint = Paint()
..color = this.color
..strokeWidth = this.thickness
..strokeCap = StrokeCap.round;
}
@override
void paint(Canvas canvas, Size size) {
final double _strokeThickness = thickness;
final double _rotationPerLine = 360 / amount;
final double _length = length/2 + _strokeThickness;
canvas.rotate(-90 * (3.1415926 / 180)); //rotate so it will start from top
for (int i = 0; i < amount; i++) {
canvas.rotate(_rotationPerLine * (3.1415926 / 180));
canvas.drawLine(Offset(0, 0.0), Offset(_length, 0.0), _paint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
However, is there a more elegant solution?
Upvotes: 1
Views: 609
Reputation: 2215
You can add separators to a new Stack
like this :
First, add the AlignmentDirectional.center
to your stack and add the new Stack to your existing Stack
Stack(
alignment: AlignmentDirectional.center,
children: [
Container(
height: 75.0,
width: 75.0,
child: CircularProgressIndicator(
strokeWidth: 6.0,
backgroundColor: Color.fromRGBO(230, 230, 230, 1.0),
valueColor: AlwaysStoppedAnimation<Color>(Color.fromRGBO(252, 90, 73, 1.0)),
value: 0.4,
),
),
Positioned(
child: Container(
height: 75.0,
width: 75.0,
child: Center(
child: Text("2 of 6"),
),
),
),
Stack(
children: buildSeparators(6),
),
],
),
and there is the buildSeparators
method
List<Widget> buildSeparators(int nbSeparators) {
var sep = <Widget>[];
for (var i = 0; i < nbSeparators; i++) {
sep.add(
Transform.rotate(
angle: i * 1 / nbSeparators * 2 * pi,
child: Container(
width: 10,
height: 81,
child: Column(
children: <Widget>[
Container(
width: 8,
height: 10,
color: Colors.white,
)
],
),
),
),
);
}
return sep;
}
It can be improved but that's the idea
Upvotes: 1