我有一个简单的倒计时文本,可以通过按钮暂停/播放。它从传递给小工具的秒数开始倒计时。我的问题是,当我快速按下暂停/播放按钮时,计时器开始倒计时的速度更快。我猜这是因为toggleTimer当按钮被多次按下时运行的()方法触发了定时器周期函数的两个示例。我如何修改这个逻辑?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:quickrest/styles/text_styles.dart';
import 'package:quickrest/styles/color_styles.dart';
import 'package:liquid_progress_indicator/liquid_progress_indicator.dart';
class ActiveTimerScreen extends StatefulWidget {
const ActiveTimerScreen({super.key, required this.seconds});
final int seconds;
@override
State<ActiveTimerScreen> createState() => _ActiveTimerScreenState();
}
class _ActiveTimerScreenState extends State<ActiveTimerScreen> {
int _timeLeft = 0;
bool timerStarted = false;
@override
void initState() {
super.initState();
_timeLeft = widget.seconds;
/// Have timer start by default.
timerStarted = true;
toggleTimer();
}
@override
Widget build(BuildContext context) {
return Material(
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(width: double.infinity),
Padding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.height * 0.3,
),
child: Text(
'${_timeLeft ~/ 60} : ${(_timeLeft % 60).toString().padLeft(2, '0')}',
style: activeTimerTitleTextStyle,
),
),
Padding(
padding: const EdgeInsets.only(
top: 80.0,
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
backgroundColor: Colors.black,
),
onPressed: () {
setState(() {
if (timerStarted) {
timerStarted = false;
} else {
timerStarted = true;
toggleTimer();
}
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
!timerStarted ? Icons.play_arrow : Icons.pause,
size: 100,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 80.0),
child: OutlinedButton(
onPressed: () {
Navigator.of(context).pop();
},
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: const BorderSide(
color: Colors.white,
),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(24),
),
),
),
child: const Text(
"Cancel",
style: activeTimerCancelTextStyle,
),
),
),
],
),
),
);
}
void toggleTimer() {
const oneSec = Duration(seconds: 1);
Timer.periodic(oneSec, (Timer t) {
if (_timeLeft < 1 || timerStarted == false) {
t.cancel();
} else {
setState(() {
_timeLeft = _timeLeft - 1;
});
}
});
}
}
1条答案
按热度按时间ffscu2ro1#
您正在启动不同的计时器,然后每秒独立执行多次:
如果在_ActiveTimerScreenState中添加
然后你的toggleTimer方法应该看起来像这样:
它不会启动不同的计时器。
而且,实际上您并没有使用toggleTimer来切换;您只使用它来启动新的计时器(您只在timerStarted为false时调用它)。您可能希望将它重命名为类似launchNewTimer的名称。您还可以在按下按钮时停止/取消旧的计时器: