Max
Max

Reputation: 1311

How to make a spinning circle animation during a countdown in flutter?

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

Answers (2)

Kaushik Chandru
Kaushik Chandru

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

Jacob Miller
Jacob Miller

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

Related Questions