構築時に渡された値を入力して、小数点第 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")
],
),
);
}
結果 :
また、カウントダウンタイマークラスから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