Im developing a soccer match schedule application .
I want to add a countdown when kick off the match.
How to best practice make a countdown widget with the format hh : mm : ss ?
Both in the comment will have good results. It is also best to rely on Flutter documentation for guidance.
With that, I've made a little sample of a countdown timer based on your requirements.
First, I've tried to define what kind of input I'm going to use. Decided to implement the input this way:
//Update the time in 'YYYY-MM-DD HH:MM:SS' format
final eventTime = DateTime.parse('2021-01-09 03:41:00');
So that I can supply the exact date and time I needed.
Then get the difference from the current date and time and convert it to seconds:
int timeDiff = eventTime.difference(DateTime.now()).inSeconds;
Then created a function that would handle the clocking of the timer:
void handleTick() {
if (timeDiff > 0) {
if (isActive) {
setState(() {
if (eventTime != DateTime.now()) {
timeDiff = timeDiff - 1;
} else {
print('Times up!');
//Do something
}
});
}
}
}
So when the timer is working as expected, I've just used mathematical operation to define the remaining days, hours, minutes and seconds:
int days = timeDiff ~/ (24 * 60 * 60) % 24;
int hours = timeDiff ~/ (60 * 60) % 24;
int minutes = (timeDiff ~/ 60) % 60;
int seconds = timeDiff % 60;
If you just need the HH:MM:SS
format you can just play around and omit that section, check the working code:
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(TimerApp());
class TimerApp extends StatefulWidget {
@override
_TimerAppState createState() => _TimerAppState();
}
//Update the time in 'YYYY-MM-DD HH:MM:SS' format
final eventTime = DateTime.parse('2021-01-09 03:41:00');
class _TimerAppState extends State<TimerApp> {
static const duration = const Duration(seconds: 1);
int timeDiff = eventTime.difference(DateTime.now()).inSeconds;
bool isActive = false;
Timer timer;
void handleTick() {
if (timeDiff > 0) {
if (isActive) {
setState(() {
if (eventTime != DateTime.now()) {
timeDiff = timeDiff - 1;
} else {
print('Times up!');
//Do something
}
});
}
}
}
@override
Widget build(BuildContext context) {
if (timer == null) {
timer = Timer.periodic(duration, (Timer t) {
handleTick();
});
}
int days = timeDiff ~/ (24 * 60 * 60) % 24;
int hours = timeDiff ~/ (60 * 60) % 24;
int minutes = (timeDiff ~/ 60) % 60;
int seconds = timeDiff % 60;
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.grey[700],
title: Center(
child: Text('Countdown Timer'),
),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
LabelText(
label: 'DAYS', value: days.toString().padLeft(2, '0')),
LabelText(
label: 'HRS', value: hours.toString().padLeft(2, '0')),
LabelText(
label: 'MIN', value: minutes.toString().padLeft(2, '0')),
LabelText(
label: 'SEC', value: seconds.toString().padLeft(2, '0')),
],
),
SizedBox(height: 60),
Container(
width: 200,
height: 47,
margin: EdgeInsets.only(top: 30),
child: RaisedButton(
color: isActive ? Colors.grey : Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25)),
child: Text(isActive ? 'STOP' : 'START'),
onPressed: () {
setState(() {
isActive = !isActive;
});
},
),
)
],
),
),
),
);
}
}
class LabelText extends StatelessWidget {
LabelText({this.label, this.value});
final String label;
final String value;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 5),
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: Colors.grey,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'$value',
style: TextStyle(
color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
Text(
'$label',
style: TextStyle(
color: Colors.white70,
),
),
],
),
);
}
}
Here is the output of the countdown timer I've created: