我正在尝试在 Flutter 中创建一个倒数计时器,它每 5 秒打印一次剩余时间,直到计时器用完,然后为列表中的下一个值运行相同的倒数计时器值(value)观。
下面的递归函数会关闭,但它会在转到 List
中的下一个值之前等待“迭代”,即使该 Timer
的剩余时间较少.
import 'dart:async';
Future main() async {
final _sequence = [21, 10, 8];
final _iteration = 5;
void _countdown(seq) async {
if (seq.length > 0) {
var duration = seq[0];
print('Starting at $duration');
Timer.periodic(Duration(seconds: _iteration), (timer) {
var remaining = duration - timer.tick * _iteration;
if (remaining >= 0) {
print('$duration, $remaining');
} else {
timer.cancel();
_countdown(seq.sublist(1));
}
});
}
}
_countdown(_sequence);
}
每次运行的持续时间都由 _sequence
列表中的值定义。
即使使用 CountdownTimer
(而不是 Timer.periodic
)也有同样的问题,当剩余值小于迭代时等待时间太长:
import 'package:quiver/async.dart';
main() {
final _sequence = [21, 10, 8];
final _iteration = 5;
void _countdown(seq) {
if (seq.length > 0) {
var duration = seq[0];
print('Starting at $duration');
CountdownTimer countdownTimer = CountdownTimer(
Duration(seconds: duration),
Duration(seconds: _iteration),
);
var sub = countdownTimer.listen(null);
sub.onData((timer) {
if (timer.remaining > Duration(seconds: 0)) {
print('$duration, ${timer.remaining.inSeconds}');
} else {
sub.cancel();
_countdown(seq.sublist(1));
}
});
}
}
_countdown(_sequence);
}
结果应如下所示,除非另有说明,否则行与行之间有 5 秒的停顿:
Starting at 21
21, 16
21, 11
21, 6
21, 1 <-- This one should only pause 1 second before continuing
Starting at 10
10, 5
10, 0 <-- This one should immediately continue
Starting at 8
8, 3 <-- This one should only pause 3 seconds before continuing
最佳答案
Dart/Flutter 支持使用 CountDownTimer 进行倒计时。下面是 2 个示例,一个没有 UI,一个在屏幕中央有一个简单的文本(超时 = 10 秒,步长 = 1 秒,您可以更改为任何您想要的)
示例 1:
import 'package:quiver/async.dart';
void main() {
const timeOutInSeconds = 10;
const stepInSeconds = 2;
int currentNumber = 0;
CountdownTimer countDownTimer = new CountdownTimer(
new Duration(seconds: timeOutInSeconds),
new Duration(seconds: stepInSeconds));
var sub = countDownTimer.listen(null);
sub.onData((duration) {
currentNumber += stepInSeconds;
int countdownNumber = timeOutInSeconds - currentNumber;
// Make it start from the timeout value
countdownNumber += stepInSeconds;
print('Your message here: $countdownNumber');
});
sub.onDone(() {
print("I'm done");
sub.cancel();
});
}
示例 2:
import 'package:flutter/material.dart';
import 'package:quiver/async.dart';
void main() {
runApp(new MaterialApp(home: new CountdownTimerPage()));
}
class CountdownTimerPage extends StatefulWidget {
@override
CountdownTimerPageState createState() => new CountdownTimerPageState();
}
class CountdownTimerPageState extends State<CountdownTimerPage> {
final timeOutInSeconds = 10;
final stepInSeconds = 2;
int currentNumber = 0;
CountdownTimerPageState() {
setupCountdownTimer();
}
setupCountdownTimer() {
CountdownTimer countDownTimer = new CountdownTimer(
new Duration(seconds: timeOutInSeconds),
new Duration(seconds: stepInSeconds));
var sub = countDownTimer.listen(null);
sub.onData((duration) {
currentNumber += stepInSeconds;
this.onTimerTick(currentNumber);
print('Your message here: $currentNumber');
});
sub.onDone(() {
print("I'm done");
sub.cancel();
});
}
void onTimerTick(int currentNumber) {
setState(() {
currentNumber = currentNumber;
});
}
@override
Widget build(BuildContext context) {
int number = timeOutInSeconds - currentNumber;
// Make it start from the timeout value
number += stepInSeconds;
return new Scaffold(
body: new Center(
child: new Text(
"Your message here: $number",
style: new TextStyle(color: Colors.red, fontSize: 25.0),
)),
);
}
}
关于dart - 创建一个倒数计时器,每 5 秒为列表中的每个值打印一次剩余时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50479114/