flutter count down timer custom time indicator

How to make a Button with a Timer in Flutter

How to make a simple Timer in Flutter

In Flutter, you can create a simple timer using the Timer class from the Dart standard library. The Timer class allows you to schedule a callback function to be called after a certain amount of time has passed.

To do this, you will need to create a variable to hold the duration of the timer and another variable to keep track of the current timer value. You can then create a Timer object that will call a callback function every second, incrementing the current timer value until it reaches the timer duration.

To update the UI with the new timer value, you can use the setState function to rebuild the widget tree with the updated value. Finally, you can display the current timer value in the UI using a Text widget.

Here’s an example code:

int _timerDuration = 60;
int _currentTimerValue = 0;
late Timer _timer;

@override
void initState() {
super.initState();
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_currentTimerValue < _timerDuration) {
_currentTimerValue++;
} else {
_timer.cancel();
}
});
});
}

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

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: Text('$_currentTimerValue / $_timerDuration')
),
);
}
flutter simple timer

This will create a simple timer that counts up from 0 to 60 and displays the current timer value in the UI. The Timer class is used to schedule a callback function that updates the current timer value and the setState function is used to update the UI with the new value.

Make a simple Countdown Timer in Flutter

To create a simple count-down timer in Flutter, you can modify the above code to count down from the timer duration instead of counting up from 0.

Here’s the modified code:

int _timerDuration = 60;
int _currentTimerValue = 60;
late Timer _timer;

@override
void initState() {
super.initState();
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_currentTimerValue > 0) {
_currentTimerValue--;
} else {
_timer.cancel();
}
});
});
}

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

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: Text('$_currentTimerValue / $_timerDuration')
),
);
}
flutter simple count down timer

In this modified code, the _currentTimerValue is set to the same value as _timerDuration at the start to initialize the count-down timer. The Timer.periodic function is used to schedule a callback function that decrements the _currentTimerValue by 1 every second. The countdown stops when the _currentTimerValue reaches 0 and the timer is cancelled.

The rest of the code is similar to the previous example, with the setState function used to update the UI with the new timer value and a Text widget used to display the current timer value.

Countdown Timer with the buttons in Flutter

To add the start, stop, and cancel buttons to the count-down timer, you can modify the above code to include three new functions that will be called when the user taps the corresponding button.

Here’s the modified code:

int _timerDuration = 60;
int _currentTimerValue = 60;
late Timer _timer;

void _startTimer() {
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_currentTimerValue > 0) {
_currentTimerValue--;
} else {
_timer.cancel();
}
});
});
}

void _stopTimer() {
if (_timer != null) {
_timer.cancel();
}
}

void _resetTimer() {
if (_timer != null) {
_timer.cancel();
}
setState(() {
_currentTimerValue = _timerDuration;
});
}

@override
void dispose() {
if (_timer != null) {
_timer.cancel();
}
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('$_currentTimerValue / $_timerDuration'),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _startTimer,
child: Text('Start'),
),
ElevatedButton(
onPressed: _stopTimer,
child: Text('Stop'),
),
ElevatedButton(
onPressed: _resetTimer,
child: Text('Reset'),
),
],
),
],
),
),
);
}
flutter count down timer with buttons

In this modified code, three new functions have been added: _startTimer, _stopTimer, and _resetTimer. The _startTimer function is called when the user taps the Start button and starts the countdown timer. The _stopTimer function is called when the user taps the Stop button and stops the countdown timer. The _resetTimer function is called when the user taps the Reset button and resets the countdown timer to its original duration.

The UI has been updated to include a column with the current timer value and three new buttons for Start, Stop, and Reset. The ElevatedButton widget is used to create the buttons and the onPressed property is set to call the corresponding function.

How to prevent the Timer to go too fast in Flutter

If you want to prevent the timer from going too fast without disabling the buttons, you can check if the timer is already running before starting a new one. Here’s an example of how you can modify the _startTimer function to do this:

void _startTimer() {
if (_timer != null && _timer!.isActive) {
return;
}
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_currentTimerValue > 0) {
_currentTimerValue--;
} else {
_timer!.cancel();
}
});
});
}

In this modified code, we first check if the timer is not null and is currently running (using the isActive property). If it is, we simply return without starting a new timer. This way, even if the start button is pressed multiple times, the timer will not go too fast.

int _timerDuration = 60;
int _currentTimerValue = 60;
Timer? _timer;

void _startTimer() {
if (_timer != null && _timer!.isActive) {
return;
}
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_currentTimerValue > 0) {
_currentTimerValue--;
} else {
_timer!.cancel();
}
});
});
}

void _stopTimer() {
if (_timer != null) {
_timer!.cancel();
}
}

void _resetTimer() {
if (_timer != null) {
_timer!.cancel();
}
setState(() {
_currentTimerValue = _timerDuration;
});
}

@override
void dispose() {
if (_timer != null) {
_timer!.cancel();
}
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('$_currentTimerValue / $_timerDuration'),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _startTimer,
child: Text('Start'),
),
ElevatedButton(
onPressed: _stopTimer,
child: Text('Stop'),
),
ElevatedButton(
onPressed: _resetTimer,
child: Text('Reset'),
),
],
),
],
),
),
);
}

Countdown Timer controlled with one button

To control the countdown Timer with one button you can use this code:

late Timer _timer;
late int _timerDuration;
late int _currentTimerValue;
late bool _isTimerRunning;

@override
void initState() {
  super.initState();
  _timerDuration = 60;
  _currentTimerValue = _timerDuration;
  _isTimerRunning = false;
}

void _toggleTimer() {
  if (!_isTimerRunning) {
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        if (_currentTimerValue > 0) {
          _currentTimerValue--;
        } else {
          _timer.cancel();
        }
      });
    });
  } else {
    _timer.cancel();
  }

  setState(() {
    _isTimerRunning = !_isTimerRunning;
  });
}

void _resetTimer() {
  if (_isTimerRunning) {
    _timer.cancel();
    _isTimerRunning = false;
  }
  setState(() {
    _currentTimerValue = _timerDuration;
  });
}

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

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('flutterassets.com'),
    ),
    body: Container(
        alignment: Alignment.topCenter,
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Text('$_currentTimerValue / $_timerDuration'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _toggleTimer,
              child: Text(_isTimerRunning ? 'Stop' : 'Start'),
              onLongPress: _resetTimer,
            ),
            SizedBox(height: 10),
            Text('Long press to reset'),
          ],
        ),
    ),
  );
}
flutter count down timer with one button

In the above code, there is a function _toggleTimer() which is responsible for controlling the timer. When the button is pressed, it checks whether the timer is running or not using the _isTimerRunning boolean variable.

If the timer is not running, it starts the timer using the Timer.periodic function which runs a given function every second. In this case, it calls the anonymous function that checks if the current timer value is greater than zero, and if so, decrements it. If the timer value becomes zero, it cancels the timer by calling the cancel() method.

If the timer is already running, it cancels the timer by calling the cancel() method.

After starting or stopping the timer, _toggleTimer() changes the _isTimerRunning boolean variable to the opposite value using the setState() function, which triggers a rebuild of the widget.

In addition, there is a function _resetTimer() which is called when the button is long-pressed. If the timer is running, it cancels the timer and sets _isTimerRunning to false. Then, it resets the _currentTimerValue to the _timerDuration.

Finally, in the build method, the button’s text is set to ‘Start’ if the timer is not running, and ‘Stop’ if the timer is running, and the onLongPress property is set to _resetTimer. A message is displayed below the button indicating that the button can be long-pressed to reset the timer.

Countdown Timer inside the button in Flutter

To add a timer text to the button label, you can create a separate method that returns the label text based on the current timer value and timer state. Here’s how you can modify the build method to achieve this:

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Text('$_currentTimerValue / $_timerDuration'),
SizedBox(height: 20),
ElevatedButton(
onPressed: _toggleTimer,
onLongPress: _resetTimer,
child: Text(_getButtonLabel()),
),
SizedBox(height: 10),
Text('Long press to reset'),
],
),
),
);
}

Here, we have added a call to _getButtonLabel() to set the button text. You can define the _getButtonLabel() method as follows:

String _getButtonLabel() {
if (!_isTimerRunning) {
return 'Start $_currentTimerValue';
} else if (_currentTimerValue == 0) {
return 'Done';
} else {
return 'Stop $_currentTimerValue';
}
}
flutter count down timer with time inside buttons

This method checks whether the timer is running and returns the label text accordingly. If the timer is not running, the label will be ‘Start X’, where X is the current timer value. If the timer is running and the current value is not 0, the label will be ‘Stop X’. If the current value is 0, the label will be ‘Done’.

late Timer _timer;
late int _timerDuration;
late int _currentTimerValue;
late bool _isTimerRunning;

String _getButtonLabel() {
  if (!_isTimerRunning) {
    return 'Start $_currentTimerValue';
  } else if (_currentTimerValue == 0) {
    return 'Done';
  } else {
    return 'Stop $_currentTimerValue';
  }
}

@override
void initState() {
  super.initState();
  _timerDuration = 60;
  _currentTimerValue = _timerDuration;
  _isTimerRunning = false;
}

void _toggleTimer() {
  if (!_isTimerRunning) {
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        if (_currentTimerValue > 0) {
          _currentTimerValue--;
        } else {
          _timer.cancel();
        }
      });
    });
  } else {
    _timer.cancel();
  }

  setState(() {
    _isTimerRunning = !_isTimerRunning;
  });
}

void _resetTimer() {
  if (_isTimerRunning) {
    _timer.cancel();
    _isTimerRunning = false;
  }
  setState(() {
    _currentTimerValue = _timerDuration;
  });
}

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

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('flutterassets.com'),
    ),
    body: Container(
        alignment: Alignment.topCenter,
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            // Text('$_currentTimerValue / $_timerDuration'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _toggleTimer,
              onLongPress: _resetTimer,
              child: Text(_getButtonLabel()),
            ),
            SizedBox(height: 10),
            Text('Long press to reset'),
          ],
        ),
    ),
  );
}

Create a Countdown Timer with a time progress indicator

To add a linear progress indicator to the countdown timer, we first need to calculate the current progress based on the remaining time and the total duration of the timer. We can do this by dividing the remaining time by the total duration and using that value as the progress for the linear progress indicator.

late Timer _timer;
late int _timerDuration;
late int _currentTimerValue;
late bool _isTimerRunning;

@override
void initState() {
  super.initState();
  _timerDuration = 60;
  _currentTimerValue = _timerDuration;
  _isTimerRunning = false;
}

void _toggleTimer() {
  if (!_isTimerRunning) {
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        if (_currentTimerValue > 0) {
          _currentTimerValue--;
        } else {
          _timer.cancel();
        }
      });
    });
  } else {
    _timer.cancel();
  }

  setState(() {
    _isTimerRunning = !_isTimerRunning;
  });
}

void _resetTimer() {
  if (_isTimerRunning) {
    _timer.cancel();
    _isTimerRunning = false;
  }
  setState(() {
    _currentTimerValue = _timerDuration;
  });
}

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

@override
Widget build(BuildContext context) {

  double progress =
      (_timerDuration - _currentTimerValue) / _timerDuration.toDouble();

  return Scaffold(
    appBar: AppBar(
      title: Text('flutterassets.com'),
    ),
    body: Container(
      alignment: Alignment.topCenter,
      padding: const EdgeInsets.all(8.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          Text('Time Remaining: $_currentTimerValue seconds'),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _toggleTimer,
            child: Stack(
              alignment: Alignment.center,
              children: [
                Text(_isTimerRunning ? 'Stop' : 'Start'),
                Positioned(
                  top: 25,
                  child: Text(
                    '$_currentTimerValue',
                    style: TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.bold,
                        color: Colors.white),
                  ),
                ),
              ],
            ),
            onLongPress: _resetTimer,
          ),
          SizedBox(height: 10),
          LinearProgressIndicator(
            value: progress,
            backgroundColor: Colors.grey,
            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
          ),
        ],
      ),
    ),
  );
}
flutter count down timer linearprogressindicator

In this updated code, we added a new variable called progress which calculates the current progress of the timer based on the remaining time and total duration. We then use this value to set the value of the CircularProgressIndicator.

Circular Countdown Timer in Flutter

late int _duration = 30;
late int _remainingTime;
late Timer _timer;
late bool _isRunning;

@override
void initState() {
super.initState();
_duration;
_remainingTime = _duration;
_isRunning = false;
}

void _startTimer() {
setState(() {
_isRunning = true;
});

_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_remainingTime > 0) {
_remainingTime--;
} else {
_stopTimer();
}
});
});
}

void _stopTimer() {
_timer.cancel();

setState(() {
_isRunning = false;
_remainingTime = _duration;
});
}

void _handleTap() {
if (!_isRunning) {
_startTimer();
} else {
_stopTimer();
}
}

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

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: _handleTap,
child: Stack(
children: [
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey,
),
child: Center(
child: Text(
_isRunning ? '$_remainingTime' : 'Start',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
),
Positioned.fill(
child: CircularProgressIndicator(
value: _isRunning ? _remainingTime / _duration : 1,
backgroundColor: Colors.white,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
),
],
),
)
),
);
}
flutter count down timer circularprogressindicator

The above code implements a countdown timer with a specific design. The app consists of a container that has a fixed width and height of 100 pixels (not real pixels 🙂 ) and displays the text “Start” in the centre of the container. The container is wrapped inside a GestureDetector, which detects user tap events on the container.

When the user taps the container, the text “Start” is replaced with a countdown timer that shows the remaining time in seconds. The timer starts from a preset value, which is set to 10 seconds by default. The timer is implemented using a Timer.periodic() function that fires a callback function every second to decrement the remaining time. The remaining time is displayed in the centre of the container using a Text widget.

In addition to the countdown timer, the app also displays a CircularProgressIndicator, which covers the entire container and provides a visual representation of the remaining time. As time decreases, the progress of the CircularProgressIndicator updates accordingly.

Once the countdown timer reaches 0, the text “Start” is displayed again, and the Timer is stopped. The user can tap the container again to start the timer from the preset value.

Create a Countdown Timer in Flutter with Linear Time Indicator

Timer? _timer;
int _duration = 60;
int _remainingTime = 60;
bool _isRunning = false;

void _startTimer() {
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
setState(() {
if (_remainingTime > 0) {
_remainingTime--;
} else {
_timer?.cancel();
_isRunning = false;
}
});
});
_isRunning = true;
}

void _stopTimer() {
if (_timer != null) {
_timer?.cancel();
_isRunning = false;
}
}

@override
void dispose() {
_stopTimer();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Container(
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () {
if (_isRunning) {
_stopTimer();
setState(() {
_remainingTime = _duration;
});
} else {
_startTimer();
}
},
child: Stack(
children: [
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
),
child: Center(
child: Text(
_isRunning ? '$_remainingTime' : 'Start',
style: TextStyle(fontSize: 24, color: Colors.white),
),
),
),
AnimatedOpacity(
opacity: _isRunning ? 1.0 : 0.0,
duration: Duration(milliseconds: 500),
child: Container(
width: 100.0 * (_remainingTime / _duration),
height: 100,
color: Colors.white.withOpacity(0.5),
),
),
],
),
),
// )
),
);
}
flutter count down timer custom linear indicator

The code creates a countdown timer with a custom design. When the app starts, a container with a “Start” text in the centre is displayed. When the user taps on the container, the timer starts and the text changes to show the remaining time in seconds.

The timer is implemented using a Timer.periodic() function and updates the remaining time every second. The timer is also displayed using a second container that covers the first one using a stack widget. The second container has a blend mode to give the effect of a linear time indicator that contracts as the time runs out.

When the timer reaches 0, it stops, and the text in the centre changes back to “Start”. The user can tap the container again to start the timer from the beginning.

Overall, the code creates a simple and visually appealing countdown timer using Flutter, with the added feature of a custom linear time indicator.