创建一个倒数计时器,该计时器每5秒为列表中的每个值打印一次剩余时间 [英] Create a countdown timer that prints a remaining time every 5 seconds for each value in a list

查看:116
本文介绍了创建一个倒数计时器,该计时器每5秒为列表中的每个值打印一次剩余时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Flutter中创建一个倒数计时器,该计时器会每5秒打印一次剩余时间,直到计时器用完为止,然后为列表中的下一个值运行相同的倒数计时器值.

I'm trying to create a countdown timer in Flutter that prints the remaining time every 5 seconds until the timer runs out, and then runs the same countdown timer for the next value in a list of values.

以下递归函数已关闭,但即使该

The following recursive function gets close, but it waits the "iteration" before going to the next value in the List even when there is less time remaining for that 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 列表中的值定义.

Each time it runs the duration is defined by the value in the _sequence List.

即使使用 CountdownTimer (而不是 Timer.periodic ),也存在同样的问题,即当剩余值小于迭代次数时,等待时间太长:

Even using the CountdownTimer (instead of Timer.periodic) has the same problem with waiting too long when the value remaining is less than the iteration:

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秒钟的暂停,除非另有说明:

The results should look like this with a 5 second pause between lines except where noted:

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,一个在屏幕中心有一个简单的Text(超时= 10秒,step = 1秒,您可以更改为所需的任何内容)

Dart/Flutter supports countdown with CountDownTimer. Below are 2 examples, one without UI and one with a simple Text at center of screen (The timeout = 10 seconds and the step = 1 seconds, you can change to whatever you want)

示例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),
      )),
    );
  }
}

这篇关于创建一个倒数计时器,该计时器每5秒为列表中的每个值打印一次剩余时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆