1

Im developing a soccer match schedule application see image. 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 ?

Kitereative Indonesia
  • 1,097
  • 6
  • 19
  • 39
  • 1
    https://stackoverflow.com/questions/52944180/date-countdown-in-dart/52945049#52945049 - here is example of countdown timer – Andrii Turkovskyi Nov 20 '18 at 13:31
  • Use platform timers. Your application has no guarantee to continue running when the screen is off. https://stackoverflow.com/questions/41924890/how-do-i-run-code-in-the-background-even-with-the-screen-off – user1462442 Nov 20 '18 at 17:59

1 Answers1

3

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:

enter image description here

MαπμQμαπkγVπ.0
  • 5,887
  • 1
  • 27
  • 65