timer - flutter 倒数计时器

标签 timer dart flutter countdown

如何将传递的值放入构造中,制作一个四舍五入到小数点后一位并显示在我的 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 的示例:

点击按钮时,从 100 开始倒计时:

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")
      ],
    ),
  );
}

结果:

Flutter countdown timer example

您也可以使用 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/

相关文章:

list - 在 forEach 循环中填充列表之前,我的异步调用正在返回

firebase - Flutter 从 QuerySnapshot 转换为 Future <List<Map<dynamic,dynamic>>>

swift - 使用计时器在后台刷新应用程序

android - java.lang.IllegalStateException : TimerTask is scheduled already: Rationally using of Timer and TimerTask in Android 错误

c# - 定时器控制增量计数器

在android上 flutter 闪屏

flutter - 当 AppLifeCycleState.detached 被调用时?

java - 使用java定时器

flutter - 参数类型 'List<dynamic>' 无法分配给参数类型 'List<SingleChildWidget>'

Dart 异步执行