您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

颤动倒数计时器

颤动倒数计时器

Here is an example usingTimer.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) => setState(
      () {
        if (_start < 1) {
          timer.cancel();
        } else {
          _start = _start - 1;
        }
      },
    ),
  );
}

@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 :

Flutter countdown timer
example

You can also use theCountdownTimer class from thequiver.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")
      ],
    ),
  );
}

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

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 aRestartableTimer 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

其他 2022/1/1 18:19:58 有547人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶