[![enter image description here][1]][1]
[1]: .png**strong text**
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
body: Center(child: RotatingCircularProgress()),
),
));
}
class RotatingCircularProgress extends StatefulWidget {
const RotatingCircularProgress({super.key});
@override
State<RotatingCircularProgress> createState() => _RotatingCircularProgressState();
}
class _RotatingCircularProgressState extends State<RotatingCircularProgress>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(); // Infinite rotation
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
height: 100,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Rotate whole indicator
child: CustomPaint(
painter: CircularProgressPainter(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircularProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = size.width / 2;
final strokeWidth = 10.0;
const startAngle = pi;//-pi / 2; // Start from top
const sweepAngle = pi*1.7;//1.8 * pi; // ¾ circle
// Gradient from green (start) to white (end)
final gradient = SweepGradient(
colors: [
Colors.green, // Start Green
Colors.green.withOpacity(0.7),
Colors.green.withOpacity(0.4),
Colors.green.withOpacity(0.1),
Colors.white, // End White
],
stops: const [0.0, 0.3, 0.6, 0.85, 1.0], // Smooth transition
tileMode: TileMode.clamp, // Avoids unwanted repetition
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(center: center, radius: radius))
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round; // Rounded at the start
// Draw arc
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
how to make custom circular progress indicator as in the pic. I've tried multiple ways but i am unable to achieve something like the one in the picture.I am trying to build exactly as in the picture. I'm new to animations. Help or guidance is highly appreciated.
[![enter image description here][1]][1]
[1]: https://i.sstatic.net/bZSXtA7U.png**strong text**
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
body: Center(child: RotatingCircularProgress()),
),
));
}
class RotatingCircularProgress extends StatefulWidget {
const RotatingCircularProgress({super.key});
@override
State<RotatingCircularProgress> createState() => _RotatingCircularProgressState();
}
class _RotatingCircularProgressState extends State<RotatingCircularProgress>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(); // Infinite rotation
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
height: 100,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Rotate whole indicator
child: CustomPaint(
painter: CircularProgressPainter(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircularProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = size.width / 2;
final strokeWidth = 10.0;
const startAngle = pi;//-pi / 2; // Start from top
const sweepAngle = pi*1.7;//1.8 * pi; // ¾ circle
// Gradient from green (start) to white (end)
final gradient = SweepGradient(
colors: [
Colors.green, // Start Green
Colors.green.withOpacity(0.7),
Colors.green.withOpacity(0.4),
Colors.green.withOpacity(0.1),
Colors.white, // End White
],
stops: const [0.0, 0.3, 0.6, 0.85, 1.0], // Smooth transition
tileMode: TileMode.clamp, // Avoids unwanted repetition
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(center: center, radius: radius))
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round; // Rounded at the start
// Draw arc
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
how to make custom circular progress indicator as in the pic. I've tried multiple ways but i am unable to achieve something like the one in the picture.I am trying to build exactly as in the picture. I'm new to animations. Help or guidance is highly appreciated.
Share Improve this question asked Feb 6 at 2:03 prabin maharjanprabin maharjan 8671 gold badge8 silver badges15 bronze badges1 Answer
Reset to default 2I just adjusted startAngle
and sweepAngle
, might achieve what you want
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
body: Center(child: RotatingCircularProgress()),
),
));
}
class RotatingCircularProgress extends StatefulWidget {
const RotatingCircularProgress({super.key});
@override
State<RotatingCircularProgress> createState() => _RotatingCircularProgressState();
}
class _RotatingCircularProgressState extends State<RotatingCircularProgress>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(); // Infinite rotation
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
height: 100,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi, // Rotate whole indicator
child: CustomPaint(
painter: CircularProgressPainter(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class CircularProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final center = size.center(Offset.zero);
final radius = size.width / 2;
final strokeWidth = 10.0;
const startAngle = 0.2;//-pi / 2; // Start from top
const sweepAngle = pi*1.7 + 0.2;//1.8 * pi; // ¾ circle
// Gradient from green (start) to white (end)
final gradient = SweepGradient(
startAngle: startAngle,
endAngle: sweepAngle,
colors: [
Colors.white, // End White
Colors.green, // Start Green
],
stops: const [0.0, 1.0], // Smooth transition
tileMode: TileMode.clamp, // Avoids unwanted repetition
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(center: center, radius: radius))
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round; // Rounded at the start
// Draw arc
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
false,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}