颤动倒数计时器
如何将传递的值放入构造中,使计时器
四舍五入到小数点后一位并显示在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),
),
),
);
}
}
回答:
Here is an example using
Timer.periodic :
Countdown starts from 10
to 0
on button click :
import 'dart:async';[...]
Timer _timer;
int _start = 10;
void startTimer() {
const oneSec = const Duration(seconds: 1);
_timer = new Timer.periodic(
oneSec,
(Timer timer) => setState(
() {
if (_start < 1) {
timer.cancel();
} else {
_start = _start - 1;
}
},
),
);
}
@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")
],
),
);
}
Result :
You can also use the
CountdownTimer class from the
quiver.async library, usage is even simpler :
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")
],
),
);
}
: For the question in comments about button click behavior
With the above code which uses Timer.periodic
, a new timer will indeed be
started on each button click, and all these timers will update the same
_start
variable, resulting in a faster decreasing counter.
There are multiple solutions to change this behavior, depending on what you
want to achieve :
- disable the button once clicked so that the user could not disturb the countdown anymore (maybe enable it back once timer is cancelled)
wrap the
Timer.periodic
creation with a non null condition so that clicking the button multiple times has no effectif (_timer != null) {
_timer = new Timer.periodic(…);
}
cancel the timer and reset the countdown if you want to restart the timer on each click :
if (_timer != null) {
_timer.cancel();
_start = 10;
}
_timer = new Timer.periodic(…);
if you want the button to act like a play/pause button :
if (_timer != null) {
_timer.cancel();
_timer = null;
} else {
_timer = new Timer.periodic(…);
}
You could also use this official async
package which provides a
RestartableTimer class which extends from Timer
and adds the reset
method.
So just call _timer.reset();
on each button click.
Finally, Codepen now supports Flutter ! So here is a live example so that
everyone can play with it : https://codepen.io/Yann39/pen/oNjrVOb
以上是 颤动倒数计时器 的全部内容, 来源链接: utcz.com/qa/403352.html