'How to Check if Timer is Active Before Creating a New One

I came across this code for a timer on another thread. When you press the RaisedButton multiple times concurrently it adds a -1 second for every click thus increasing the rate of decrease.

Any ideas for the easiest way to check if the timer is already active and if it is to not let the RaisedButton create a new one. Thanks!

import 'dart:async';

[...]

Timer _timer;
int _start = 10;

void startTimer() {
  const oneSec = const Duration(seconds: 1);
  _timer = new Timer.periodic(
    oneSec,
    (Timer timer) => setState(
      () {
        if (_start < 1) {
          timer.cancel();
        } else {
          _start = _start - 1;
        }
      },
    ),
  );
}

@override
void dispose() {
  _timer.cancel();
  super.dispose();
}

Widget build(BuildContext context) {
  return new Scaffold(
    appBar: AppBar(title: Text("Timer test")),
    body: Column(
      children: <Widget>[
        RaisedButton(
          onPressed: () {
            startTimer();
          },
          child: Text("start"),
        ),
        Text("$_start")
      ],
    ),
  );
}


Solution 1:[1]

Add a check to see if _timer is already active using the isActive property of Timers. If it's already active, it won't create a new one.

Example:

void startTimer() {
  const oneSec = const Duration(seconds: 1);
  if(!_timer?.isActive) {
    _timer = new Timer.periodic(
      oneSec,
      (Timer timer) => setState(
        () {
          if (_start < 1) {
            timer.cancel();
          } else {
            _start = _start - 1;
          }
        },
      ),
    );
  }
}

Solution 2:[2]

The receiver can't be null, so the null-aware operator '?.' is unnecessary. Change this:

if(!_timer?.isActive)

to

if(!_timer.isActive)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Christopher Moore
Solution 2 jrana