Restart CircularCountdownTimer flutter onComplete

Viewed 1070

Hey im trying to have a CircularCountDownTimer restarting every time it finishes counting to 60,

I was hoping it has to do with onComplete(), but I can't figure out how to restart it.

any help appreciated, thanks.
this is the CircularTimer widget:

                        CircularCountDownTimer(

                          duration: 60,
                          width: MediaQuery.of(context).size.width,
                          height: MediaQuery.of(context).size.height,
                          color: Colors.grey[300],
                          fillColor: Colors.yellow[800],
                          strokeWidth: 4.0,
                          textStyle: TextStyle(
                              fontSize: 0.0,
                              color: Colors.black87,
                              fontWeight: FontWeight.bold),

                          isReverse: false,

                          
                          onComplete: () {

                            setState(() {
                              min --;
                            });
                            
                          },
                        )
3 Answers

I have updated my Package circular_countdown_timer and added optional CountDownController parameter named controller which is use to control (i.e Pause, Resume, Restart) the Countdown Timer. You can further check package's READ_ME and example.dart file for details. Thanks

You can copy paste run full code below
You can add Key in CircularCountDownTimer, when call setState in onComplete, CircularCountDownTimer will restart, see working demo
For demo purpose, I use 10 seconds

Step 1: Modify source code of circular_countdown_timer.dart add Key key and super(key: key) in constructor

    CircularCountDownTimer(
      { Key key,  //add here
        @required this.width,
      @required this.height,
      @required this.duration,
      @required this.fillColor,
      @required this.color,
      this.isReverse,
      this.onComplete,
      this.strokeWidth,
      this.textStyle})  :
        assert(width != null),
  assert(height != null),
  assert(duration != null),
  assert(fillColor != null),
  assert(color != null)
  , super(key: key); //add here

Step 2: In your code, Provide UniqueKey() to CircularCountDownTimer

child: CircularCountDownTimer(
          key: UniqueKey(),

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:circular_countdown_timer/circular_countdown_timer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Circular Countdown Timer Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Circular Countdown Timer'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
            child: CircularCountDownTimer(
          key: UniqueKey(),
          duration: 10,
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          color: Colors.grey[300],
          fillColor: Colors.yellow[800],
          strokeWidth: 4.0,
          textStyle: TextStyle(
              fontSize: 0.0,
              color: Colors.black87,
              fontWeight: FontWeight.bold),
          isReverse: false,
          onComplete: () {
            print("complete");
            setState(() {
              //min--;
            });
          },
        )));
  }
}

You can use ChangeNotifier from provider package to rebuild the widget. Here is an example.

import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ChangeWidget()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Consumer<ChangeWidget>(
            builder: (context, snapshot, _) {
              return snapshot.init;
            },
          ),
        ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          Provider.of<ChangeWidget>(context, listen: false)
              .playPause();
        },
        child: Icon(Icons.close),
      ),
    );
  }
}

class ChangeWidget extends ChangeNotifier {
  int _i = 0;
  bool _run = true;
  playPause(){
    if(_run){
      _run = false;
    }else{
      _run = true;
      restart();
    }
  }
  Widget init = Builder(
      key: Key("0"),
      builder: (context) => CircularCountDownTimer(
            duration: 10,
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            color: Colors.grey[300],
            fillColor: Colors.yellow[800],
            strokeWidth: 4.0,
            textStyle: TextStyle(
                fontSize: 0.0,
                color: Colors.black87,
                fontWeight: FontWeight.bold),
            isReverse: false,
            onComplete: () {
              Provider.of<ChangeWidget>(context, listen: false)
                  .restart();
            },
          ));

  restart() {
    _i++;
    init = Builder(
        key: Key(_i.toString()),
        builder: (context) => CircularCountDownTimer(
              duration: 10,
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              color: Colors.grey[300],
              fillColor: Colors.yellow[800],
              strokeWidth: 4.0,
              textStyle: TextStyle(
                  fontSize: 0.0,
                  color: Colors.black87,
                  fontWeight: FontWeight.bold),
              isReverse: false,
              onComplete: () {
                if(_run){
                  restart();
                }
              },
            ));
    notifyListeners();
  }
}
Related