1

I am trying to make a simple timer to know how much time has passed from a date to a current date

but the problem I have is that the Text widget is only painted once but it does not update, and I would like the text to update every 1 second. And not have to refresh the page, is it possible to do that?

import 'package:flutter/material.dart';

class TimerPage extends StatefulWidget {
  @override
  _TimerPageState createState() => _TimerPageState();
}

class _TimerPageState extends State<TimerPage> {
  @override
  Widget build(BuildContext context) {

    final start = DateTime(2020, 8, 10, 16, 30, 0);
    final currentdate= DateTime.now();
    final comparation = currentdate.difference(start);

    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(vertical: 20),
          child: Center(
              child: Column(
            children: <Widget>[
              Text("Start time: " + start.toString()),
              Divider(),
              Text(
                "time elapsed = " + comparation.toString().substring(0, 7),
                style: TextStyle(color: Color(0xff5abd8c), fontSize: 26),
              )
            ],
          )),
        ),
      ),
    );
  }
}

I try this:

Timer timer;
  final start = DateTime(2020, 8, 17, 21, 30, 0);
  final dateActual = DateTime.now();
  Duration comparation = new Duration(hours: 0, minutes: 0, seconds: 0);
  @override
  void initState() {
    timer = Timer.periodic(Duration(seconds: 1), (_) {
      setState(() {
        comparation = dateActual.difference(start);
        print(comparation);
      });
    });
  }

  @override
  void dispose() {
    timer?.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(vertical: 20),
          child: Center(
              child: Column(
            children: <Widget>[
              Text("Start time: " + start.toString()),
              Divider(),
              Text(
                "time elapsed = " + comparation.toString().substring(0, 7),
                style: TextStyle(color: Color(0xff5abd8c), fontSize: 26),
              )
            ],
          )),
        ),
      ),
    );
  }
}
7
  • Have you tried my solution? Commented Aug 12, 2020 at 21:50
  • @ChristopherMoore Hi! Yes I tried but it didn't work for me Commented Aug 16, 2020 at 16:48
  • What did not work? Commented Aug 16, 2020 at 17:21
  • @ChristopherMoore I update the question, this is what a tried Commented Aug 18, 2020 at 3:48
  • You changed your original code. That's why it didn't work. Commented Aug 18, 2020 at 3:48

1 Answer 1

3

To do this, you want a Timer from the dart:async library, specifically a Timer.periodic.

Instantiate one in initState of your StatefulWidget and cancel it in dispose.

Timer.periodic takes a callback that fires after every duration that's passed. Since your DateTime difference calculation is already done in build, you just need to trigger a rebuild with setState.

Timer timer;

@override
void initState() {
  timer = Timer.periodic(Duration(seconds: 1), (_) {
    setState(() {});
  });
}

@override
void dispose() {
  timer?.cancel();
}

It's not possible to do this without rebuilding, at the very least, the Text widget that's being changed. I don't think it's necessary since there isn't much in this build method, but if you wanted to do that, you would have to extract all of the necessary time calculations, timer, and single Text widget to its own StatefulWidget, so that only the one widget that's necessary to be rebuilt, is rebuilt.

Ideally, you should also be doing the time calculations outside of the build method, but it's not a huge deal in this case and you'll get something that works.

Sign up to request clarification or add additional context in comments.

2 Comments

I had to change the first line to Timer? timer;, otherwise, it was giving me not initialized error.
@TrigonaMinima This answer was made before null-safety in Dart was a thing. Doing late final Timer timerl would be even better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.