Diego Gamboa
Diego Gamboa

Reputation: 43

handle multiple timers with the class timer

I've trying to do a multiple timer in flutter, when one ends, another one should start, for some reason, when the first timer ends, the next one doesn't begin. Here is the code

  Timer timer;
    
  //Create the sets
  void startSets(){
    startTimer(10,0); //10 seconds, 0 minutes
      for(int i=0; i<sets;i++){
        for(int j=0;j<exercises;j++){
          startTimer(15,0); //15 seconds, 0 minutes
        }
        startTimer(12,0); //12 seconds, 0 minutes
      }
  }

  void stopTimer(){ 
    timer.cancel();
  }

  void startTimer(int seconds, int minutes){ 
    timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        if(seconds>0){
          seconds--;
        }else if(seconds==0 && minutes>0){
          minutes--;
          seconds = 59;
        }else{
          timer.cancel();
        }
        minText=minToString(minutes);
        secText=secToString(seconds);
      });
    });
  }

minText and secText are global variables which I use for a Text Widget

Upvotes: 0

Views: 1772

Answers (2)

jamesdlin
jamesdlin

Reputation: 89965

Your code doesn't match your description. You say you want one Timer to start when another one ends, but startSets start all its Timers at the same time without any waiting. If you actually want only one Timer in-flight at a time, you will need to create a queue that you process when each Timer completes.

One way to do it would be something like (this is untested code):

var timerQueue = Queue<Duration>();
Timer currentTimer;
  
//Create the sets
void startSets() {
  timerQueue.add(Duration(seconds: 10));
  for (var i = 0; i < sets; i++) {
    for (var j = 0; j < exercises; j++) {
      timerQueue.add(Duration(seconds: 15));
    }
    timerQueue.add(Duration(seconds: 12));
  }

  startNextTimer();
}

void stopTimer() { 
  currentTimer?.cancel();
  currentTimer = null;
}

void startNextTimer() {
  if (timerQueue.isEmpty) {
    return;
  }

  var duration = timerQueue.removeFirst();
  var seconds = duration.inSeconds % 60;
  var minutes = duration.inMinutes;

  assert(currentTimer == null);
  currentTimer = Timer.periodic(Duration(seconds: 1), (timer) {
    setState(() {
      if (seconds > 0){
        seconds--;
      } else if (seconds == 0 && minutes > 0) {
        minutes--;
        seconds = 59;
      } else {
        currentTimer.cancel();
        currentTimer = null;
      }
      minText = minToString(minutes);
      secText = secToString(seconds);

      if (currentTimer == null) {
        startNextTimer();
      }
    });
  });
}

Upvotes: 1

Biruk Telelew
Biruk Telelew

Reputation: 1193

declare timer variable inside startTimer method like this

  void startTimer(int seconds, int minutes){ 
  Timer timer;
  ...
  }

so that for every time startTimer is called it will be declared

Upvotes: 0

Related Questions