颤振倒数计时器 [英] Flutter Countdown Timer

查看:22
本文介绍了颤振倒数计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将传递的值放入构造中,制作一个四舍五入到第一个小数并显示在我的 RaisedButton 的子文本中的计时器?我试过,但没有运气.我设法使用一个简单的 Timer 使回调函数工作,但没有周期性,也没有在文本中实时更新值...

import 'package:flutter/material.dart';导入飞镖:UI";导入飞镖:异步";类 TimerButton 扩展了 StatefulWidget {最终持续时间计时器TastoPremuto;定时器按钮(this.timerTastoPremuto);@覆盖_TimerButtonState createState() =>_TimerButtonState();}class _TimerButtonState 扩展 State{@覆盖小部件构建(BuildContext 上下文){返回容器(边距:EdgeInsets.all(5.0),高度:135.0,宽度:135.0,孩子:新的凸起按钮(海拔:100.0,颜色:Colors.white.withOpacity(.8),高亮高度:0.0,按下: () {int _start = widget.timerTastoPremuto.inMilliseconds;const oneDecimal = const 持续时间(毫秒:100);定时器_timer = new Timer.periodic(一个十进制,(定时器定时器) =>设置状态((){如果 (_start <100) {_timer.cancel();} 别的 {_start = _start - 100;}}));},splashColor: Colors.red,highlightColor: Colors.red,//形状:RoundedRectangleBorder e tutto il resto uguale形状:斜角矩形边框(边:BorderSide(颜色:Colors.black,宽度:2.5),borderRadius:新的 BorderRadius.circular(15.0)),孩子:新文本("$_start",样式:new TextStyle(fontFamily: "Minim", fontSize: 50.0),),),);}}

解决方案

这里是一个使用

您还可以使用 CountdownTimer 类从 <一个 href="https://api.flutter.dev/flutter/quiver.async/quiver.async-library.html" rel="noreferrer">quiver.async 库,使用起来更简单:

import 'package:quiver/async.dart';[...]int_start = 10;int_current = 10;无效的开始定时器(){CountdownTimer countDownTimer = new CountdownTimer(新的持续时间(秒:_start),新的持续时间(秒:1),);var sub = countDownTimer.listen(null);sub.onData((持续时间){setState(() { _current = _start - duration.elapsed.inSeconds; });});sub.onDone(() {打印(完成");子取消();});}小部件构建(BuildContext 上下文){返回新的脚手架(appBar: AppBar(title: Text("Timer test")),正文:列(孩子们:<小部件>[凸起按钮(按下: () {开始定时器();},孩子:文本(开始"),),文本($_current")],),);}


EDIT:关于按钮点击行为评论中的问题

使用上面使用Timer.periodic的代码,每次点击按钮时都会启动一个新的计时器,并且所有这些计时器都会更新相同的_start变量,导致计数器下降速度更快.

有多种解决方案可以改变这种行为,具体取决于您想要实现的目标:

  • 一旦点击就禁用按钮,这样用户就不会再打扰倒计时(可能会在定时器取消后重新启用)
  • 使用非空条件包装 Timer.periodic 创建,以便多次单击按钮无效

if (_timer != null) {_timer = new Timer.periodic(...);}

  • 如果您想在每次点击时重新启动计时器,请取消计时器并重置倒计时:

if (_timer != null) {_timer.cancel();_开始= 10;}_timer = new Timer.periodic(...);

  • 如果你想让按钮像播放/暂停按钮一样:

if (_timer != null) {_timer.cancel();_timer = 空;} 别的 {_timer = new Timer.periodic(...);}

您也可以使用这个官方 async 包,它提供了一个 RestartableTimer 类从 Timer 扩展并添加了 reset方法.

所以只需在每次点击按钮时调用 _timer.reset();.

终于,Codepen 现在支持 Flutter 了!所以这是一个活生生的例子,这样每个人都可以玩它:https://codepen.io/Yann39/pen/oNjrVOb

How can I do to put the value passed in the construction, to make a timer that rounds to the first decimal and shows at the child text of my RaisedButton? I've tried but without luck. I manage to make work the callback function with a simple Timer but no periodic and with no update of value in real time in the text...

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

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


EDIT : 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 effect

if (_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

这篇关于颤振倒数计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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