dart - 创建一个倒数计时器,每 5 秒为列表中的每个值打印一次剩余时间

标签 dart flutter

我正在尝试在 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/

相关文章:

flutter - 制作一个简单的单实例类作为数据库助手

dart - TextFormField Flutter 没有适当改变

dart - 是否可以在 Dart 中的一行上初始化一个 List? (在 C# 中称为集合初始值设定项)

Flutter 使用 BorderRadiusTween 分离 ClipRRect 边界半径

flutter - 如何限制WebviewScaffold显示有限的内容

firebase - 将 SearchField 添加到从 Firestore 读取的 StreamBuilder

firebase - Dart 错误 : Unhandled exception: E/flutter ( 5079): Invalid argument: Instance of 'Future<String>'

flutter - 如何在我的 Flutter 应用程序中向我的 Flutter 路由添加自定义转换

flutter - 如何使用 `form.validate()` 调用特定验证器而不是同时调用所有验证器?

json - 什么是合适的 AWSJSON?