如何将传递的值放入构造中,制作一个四舍五入到小数点后一位并显示在我的 RaisedButton 子文本中的计时器?我试过但没有运气。我设法使用一个简单的 Timer 使回调函数工作,但没有周期性,也没有在文本中实时更新值......
import 'package:flutter/material.dart';
import 'dart:ui';
import 'dart:async';
class TimerButton extends StatefulWidget {
final Duration timerTastoPremuto;
TimerButton(this.timerTastoPremuto);
@override
_TimerButtonState createState() => _TimerButtonState();
}
class _TimerButtonState extends State<TimerButton> {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(5.0),
height: 135.0,
width: 135.0,
child: new RaisedButton(
elevation: 100.0,
color: Colors.white.withOpacity(.8),
highlightElevation: 0.0,
onPressed: () {
int _start = widget.timerTastoPremuto.inMilliseconds;
const oneDecimal = const Duration(milliseconds: 100);
Timer _timer = new Timer.periodic(
oneDecimal,
(Timer timer) =>
setState(() {
if (_start < 100) {
_timer.cancel();
} else {
_start = _start - 100;
}
}));
},
splashColor: Colors.red,
highlightColor: Colors.red,
//shape: RoundedRectangleBorder e tutto il resto uguale
shape: BeveledRectangleBorder(
side: BorderSide(color: Colors.black, width: 2.5),
borderRadius: new BorderRadius.circular(15.0)),
child: new Text(
"$_start",
style: new TextStyle(fontFamily: "Minim", fontSize: 50.0),
),
),
);
}
}
最佳答案
这是一个使用 Timer.periodic 的示例:
点击按钮时,从 10
到 0
开始倒计时:
import 'dart:async';
[...]
Timer _timer;
int _start = 10;
void startTimer() {
const oneSec = const Duration(seconds: 1);
_timer = new Timer.periodic(
oneSec,
(Timer timer) {
if (_start == 0) {
setState(() {
timer.cancel();
});
} else {
setState(() {
_start--;
});
}
},
);
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text("Timer test")),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
startTimer();
},
child: Text("start"),
),
Text("$_start")
],
),
);
}
结果:
您也可以使用 CountdownTimer来自 quiver.async 的类(class)库,使用更简单:
import 'package:quiver/async.dart';
[...]
int _start = 10;
int _current = 10;
void startTimer() {
CountdownTimer countDownTimer = new CountdownTimer(
new Duration(seconds: _start),
new Duration(seconds: 1),
);
var sub = countDownTimer.listen(null);
sub.onData((duration) {
setState(() { _current = _start - duration.elapsed.inSeconds; });
});
sub.onDone(() {
print("Done");
sub.cancel();
});
}
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(title: Text("Timer test")),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
startTimer();
},
child: Text("start"),
),
Text("$_current")
],
),
);
}
编辑:关于按钮点击行为的评论中的问题
上面的代码使用Timer.periodic
,每次按钮点击都会启动一个新的定时器,所有这些定时器都会更新相同的_start
变量,导致更快的递减计数器。
有多种解决方案可以改变这种行为,具体取决于您想要实现的目标:
- 一旦点击就禁用按钮,这样用户就不会再打扰倒计时了(可能会在取消计时器后重新启用它)
- 使用非空条件包装
Timer.periodic
创建,以便多次单击按钮无效
if (_timer != null) {
_timer = new Timer.periodic(...);
}
- 如果您想在每次点击时重新启动计时器,请取消计时器并重置倒计时:
if (_timer != null) {
_timer.cancel();
_start = 10;
}
_timer = new Timer.periodic(...);
- 如果您希望该按钮起到播放/暂停按钮的作用:
if (_timer != null) {
_timer.cancel();
_timer = null;
} else {
_timer = new Timer.periodic(...);
}
你也可以用这个官方async提供 RestartableTimer 的软件包从 Timer
扩展并添加 reset
方法的类。
所以只需在每个按钮点击时调用 _timer.reset();
。
最后,Codepen 现在支持 Flutter 了!所以这里是一个活生生的例子,每个人都可以玩它:https://codepen.io/Yann39/pen/oNjrVOb
关于timer - flutter 倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54610121/