Flutter カウントダウンタイマー 質問する

Flutter カウントダウンタイマー 質問する

構築時に渡された値を入力して、小数点第 1 位に丸めて RaisedButton の子テキストに表示するタイマーを作成するにはどうすればよいでしょうか。試してみましたが、うまくいきませんでした。単純なタイマーを使用してコールバック関数を動作させることはできましたが、定期的ではなく、テキスト内の値がリアルタイムで更新されません...

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

ベストアンサー1

以下は使用例ですタイマー.定期:

ボタンをクリックする10とカウントダウンが始まります:0

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 カウントダウン タイマーの例

また、カウントダウンタイマークラスからquiver.asyncライブラリを使用すると、使い方はさらに簡単になります。

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(...);
}

この公式の非同期パッケージは再起動可能なタイマーTimerから拡張され、メソッドを追加するクラスreset

_timer.reset();ボタンをクリックするたびに呼び出すだけです。

ついに、Codepen が Flutter をサポートするようになりました。ここでは、誰でも試せるライブ サンプルを紹介します。https://codepen.io/Yann39/pen/oNjrVOb

おすすめ記事