Reputation: 1120
I have created a timer that starts from 30 minutes and goes to 0. But I noticed that it only works correctly for the first 3 minutes but after that, it starts skipping minutes and sometimes stops or goes back to 0 instantly. To showcase the issue I have created a dartpad which you can run here - https://dartpad.dev/0f8bb5a5cf41f550f406c8fd7c93f3a6.
The same full code is this:-
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Timer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Timer _timer;
int _start = 30;
void startMinTimer() {
const oneMin = const Duration(minutes: 1);
_timer = new Timer.periodic(
oneMin,
(Timer timer) {
if (_start == 0) {
setState(() {
timer.cancel();
});
} else {
setState(() {
_start--;
});
}
},
);
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
//Todo: fix timer automatically resets to 0 after sometime
@override
Widget build(BuildContext context) {
startMinTimer();
return Scaffold(
appBar: AppBar(
title: Text('Timer Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Minutes Left',
),
Text(
'$_start',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
);
}
}
I want to knows what wrong is happening and how I could fix that. Thanks in advance.
Upvotes: 2
Views: 598
Reputation: 488
What happens here is that you are calling the startMinTimer()
from the build method, And each time you call the setState()
the build method is run to update the widget resulting in another call to startMinTimer()
, After that a new Timer instance is created and it starts reducing the _start
count as well. This process repeats(recursion).
To prevent this, Ensure that the startMinTimer()
is only called once. As you may know, Flutter has an initState()
method for stateful Widgets, which is only run (run once) when the widget is created. You can call the startMinTimer()
from the initState()
method to successfully implement the functionality.
Upvotes: 2