can you please help me with this code . i made a timer .
i want the timer stops when it’s value gets 1 ;
but it doesn’t . i don’t know where is the problem.
please help me . thank you.
here is the result in emulator:
here is my whole 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'))
],
),
);
}
}
2
Answers
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 printprogress
in your else branch of the timer you will see that it shows:To solve it simply don’t check for one but check if it’s higher than 0.99 for example so like
If the timer doesn’t stop when its value reaches 1, it might be due to the condition inside the timer’s callback not being met exactly due to floating-point arithmetic inaccuracies. When you increment progress by 0.1, it might not reach exactly 1 due to the way floating-point numbers are represented in computer arithmetic. Thus, the condition if (progress == 1) may never be true, causing the timer to not cancel as expected.
A better approach is to check if the progress is greater than or equal to 1. This will ensure that the timer stops even if there’s a slight arithmetic inaccuracy. Here’s how you can adjust the startTimer method:
With this adjustment, the timer will cancel as soon as progress is greater than or equal to 1, ensuring that the timer stops. Also, by checking if progress exceeds 1 after incrementing it and setting it back to 1 if it does, you can avoid having a progress value that exceeds the maximum expected value, ensuring that the CircularProgressIndicator behaves as expected.