I'm trying to use the periodic
class method Timer
inside a class that extends from (from the ProviderChangeNotifier
package ) by having my variable decrement by one every second .time
This works correctly if I don't add the method NotifyListeners
so that it redraws all the widgets that occupy the property time
, like so:
class PriceProvider extends ChangeNotifier{
int _time = 60;
int get time{
return _time;
}
void cronometer(){//método que activa el timer
Timer _timer = Timer.periodic(const Duration(seconds: 1), (Timer timer){
print(DateTime.now());//Imprimo la fecha para que vean cada cuanto tiempo se ejecuta el código
_time += -1;//decrementa time
if(_time == 0){
_time = 60;
}
// notifyListeners();
});
}
}
Console output (runs every second correctly):
On the other hand, if I uncomment the method NotifyListeners
, the code begins to execute more and more times per second exponentially (for example, first it executes once, then twice, then 5, then 9 and so on):
This is where I call the method cronometer
:
class PriceWithClock extends StatelessWidget {
@override
Widget build(BuildContext context) {
PriceProvider priceProvider = Provider.of<PriceProvider>(context);
priceProvider.cronometer();
return CircularPercentIndicator(
radius: 100.0,
lineWidth: 5.0,
percent: 1-priceProvider.time/60,
center: Text("00:${priceProvider.time}"),
),
);
}
}
I create the priceProvider
in main
my project's:
void main() async{
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => PriceProvider()),
],
child: MyApp(),
),
);
}
The problem is that you're creating the
Timer
every time it's donerebuild
, i.e. every time you use thenotifyListeners
re-enter the methodbuild
, so callcronometer
then re-create anotherTimer.
The correct way would be
Timer
to create the timer only once, or you can also create a validation so that it doesn't recreate the timer.Your class would look like this:
Another way to solve it, as I was saying, just run the
cronometer
once.Call
cronometer
when the Provider is created.