I have made a timer in a Flutter app, and I want the timer to stop when it reaches 1 second, but it doesn't. I don't know where is the problem.
Here is the code and the emulator running:
And here is the code:
class _MyHomeState extends State<MyHome> {
double progress = 0;
void startTimer() {
Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
if (progress == 1) {
timer.cancel();
} else {
progress += 0.1;
}
});
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
alignment: Alignment.center,
children: [
Text(progress.toStringAsFixed(1)),
SizedBox(
height: 300,
width: 300,
child: CircularProgressIndicator(
value: progress,
color: Colors.deepOrange,
),
)
],
),
const SizedBox(
height: 50,
),
ElevatedButton(
onPressed: () {
setState(() {
progress = 0;
startTimer();
});
},
child: const Text('Start'))
],
),
);
}
}
It's because of floating point error. In software development decimals can't be used in calculations with 100% accuracy. You can't guarantee that 0.1 + 0.1 = 0.2. The problem here is that progress
never will equal 1. If you print progress
in your else branch of the timer you will see that it shows:
0.1
0.2
0.30000000000000004
0.4
0.5
0.6
0.7
0.7999999999999999
0.8999999999999999
0.9999999999999999
1.0999999999999999
1.2
1.3
To solve it simply don't check for one but check if it's higher than 0.99 for example so like
if (progress > 0.99) {
timer.cancel();
} else {
progress += 0.1;
}