Reputation: 1311
I have a time widget that counts down 30 seconds. I have a circle around the time (I attached a screenshot below). I need to animate this circle so that when the time is counted down for 30 seconds, the circle spins, only the time reaches 00:00 the circle stops and does not spin, by pressing the button, the time counts down again for 30 seconds and the circle starts spinning. Tell me how to make an animation of a spinning circle?
class ResendLoader extends StatelessWidget {
const ResendLoader({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
context.read<TimerBloc>().add(const TimerStarted(duration: 30));
return BlocBuilder<TimerBloc, TimerState>(
buildWhen: (prev, state) => prev.runtimeType != state.runtimeType,
builder: (context, state) {
return Center(
child: Stack(
alignment: AlignmentDirectional.center,
children: [
SizedBox(
width: 70,
height: 70,
child: CustomPaint(
painter: RingPainter(
progress: 0.3,
taskCompletedColor: Colors.white,
taskNotCompletedColor:
constants.Colors.greyDark.withOpacity(0.5)),
),
),
_timerText(context),
],
),
);
},
);
}
class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final strokeWidth = size.width / 15.0;
final center = Offset(size.width / 2, size.height / 2);
final radius = (size.width - strokeWidth) / 2;
var paint1 = Paint()
..color = const Color(0xff63aa65)
..style = PaintingStyle.fill;
//a circle
canvas.drawCircle(center, radius, paint1);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
Upvotes: 0
Views: 812
Reputation: 17822
You can use AnimatedRotation widget and animate its turns like this
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(home: AnimatedCircle());
}
}
class AnimatedCircle extends StatefulWidget {
const AnimatedCircle({Key? key}) : super(key: key);
@override
State<AnimatedCircle> createState() => _AnimatedCircleState();
}
class _AnimatedCircleState extends State<AnimatedCircle> {
double rotation = 0;
int seconds = 30;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaterialButton(
color: Colors.blue,
child: Text("Start Animation"),
onPressed: () {
seconds = 30;
rotation = 0;
startAnimation();
}),
SizedBox(
height: 20,
),
MaterialButton(
color: Colors.blue,
child: Text("Stop Animation"),
onPressed: () {
seconds = 0;
setState(() {});
}),
SizedBox(
height: 20,
),
AnimatedRotation(
turns: rotation,
duration: Duration(seconds: 1),
curve: Curves.linear,
child: Stack(
alignment: AlignmentDirectional.center,
children: [
SizedBox(
width: 70,
height: 70,
child: CustomPaint(
painter: RingPainter(
progress: 0.3,
taskCompletedColor: Colors.white,
taskNotCompletedColor:
constants.Colors.greyDark.withOpacity(0.5)),
),
),
SizedBox(
height: 20,
),
Text("Seconds: $seconds")
],
),
),
);
}
startAnimation() {
//To slow down the animation
rotation += 0.5;
seconds--;
setState(() {});
if (seconds >= 0) {
Future.delayed(Duration(seconds: 1), () {
startAnimation();
});
}
}
}
Upvotes: 1
Reputation: 754
Use a FutureBuilder, the future is a this: Future.delayed(Duration(minutes: 1))
After a minute, the builder will update to complete. Change the minutes to whatever you want, you can do minutes, seconds, hours, etc.
In the builder, have an if statement to check the status. in the else, return a CircularProgressIndicator widget. That's what you want.
See the docs: https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
FYI, you have way more code than you need.
Upvotes: 1