我正在尝试使此计时器工作。很抱歉混乱,但尝试很多。最好的制作方法是什么?我开始感到困惑。我希望该时间= 30,直到更新为0.1时达到0,然后播放警报声音。
import 'package:flutter/material.dart';
import 'dart:ui';
import 'dart:async';
class TimerButton extends StatefulWidget {
final int time = 30;
@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: () {
startTimer(widget.time);
};
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),
),
),
);
}
}
int startTimer(int time){
Timer _timer;
int _start = time;
const oneSec = const Duration(milliseconds: 100);
_timer = new Timer.periodic(oneSec, (Timer timer) {
_TimerButtonState().setState((){
if (_start < 0.1) {
timer.cancel();
} else {
_start = _start - 100;
}
});
});
}
答案 0 :(得分:0)
import 'package:flutter/material.dart';
import 'dart:ui';
import 'dart:async';
const oneTick = const Duration(milliseconds: 100);
class TimerButton extends StatefulWidget {
/// desired duration in seconds
final int time;
TimerButton({Key key, this.time: 30}): super(key:key);
@override
TimerButtonState createState() => _TimerButtonState();
}
class TimerButtonState extends State<TimerButton>
with SingleTickerProviderStateMixin {
/// timer instance
Timer _timer;
/// holds number of millis till end
int _millisLeft;
/// holds total desired duration
Duration _totalDuration;
@override
void initState() {
// create convertable duration object with desired number of seconds
_totalDuration = Duration(seconds: widget.time);
resetTimer();
}
@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: () {
// reset
resetTimer();
startTimer();
},
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(
formatTime(_millisLeft),
style: new TextStyle(fontFamily: "Minim", fontSize: 50.0),
),
),
);
}
void resetTimer() {
setState(() {
// cancel if any
_timer?.cancel();
// reset value to begin from
_millisLeft = _totalDuration.inMilliseconds;
});
}
void startTimer() {
setState(() {
_timer = new Timer.periodic(oneTick, onTick);
});
}
void onTick(Timer timer) {
print(_millisLeft);
setState(() {
// stop when lower then 1 tick duration
if (_millisLeft < oneTick.inMilliseconds) {
timer.cancel();
} else {
// subtract one tick
_millisLeft -= oneTick.inMilliseconds;
}
});
}
/// divide by 1000 to сonvert millis to seconds (in double precision),
/// then use toStringAsFixed(number of precision digits after comma)
String formatTime(int ms) {
return (ms / 1000).toStringAsFixed(2);
}
}
用法
TimerButton()
或
TimerButton(seconds:420)
已添加回答您的评论:
1)要能够从外部重置它:
在单独的文件中keys.dart
注册一个全局密钥(每个应用程序执行一次,我的意思是不要重复此行)
GlobalKey<TimerButtonState> timerKey = GlobalKey<TimerButtonState>();
然后,当您创建计时器时,将此键传递给它
... your screen or whatever
import '../keys.dart'
...
TimerButton(key: timerKey, time:50)
...
onClick: timerKey.currentState.resetTimer //shorthand syntax
onClick: () {
timerKey.currentState.resetTimer();
} // for sure
2)要将值从小部件传递给父级:
class TimerButton extends StatefulWidget {
/// desired duration in seconds
final int time;
final Function(Duration) onTicked;
TimerButton({Key key, this.time: 30, this.onTicked}): super(key:key);
@override
TimerButtonState createState() => _TimerButtonState();
}
...
//in state:
...
void onTick(Timer timer) {
print(_millisLeft);
setState(() {
if (_millisLeft < oneTick.inMilliseconds) {
timer.cancel();
widget.onStopped(); // tell whoever interested that it's stopped
} else {
// subtract one tick
_millisLeft -= oneTick.inMilliseconds;
widget.onTicked(_millisLeft); // tell about updates
}
});
}
// in parent:
...
TimerButton(key: timerKey,
time:50,
onStop: (){ parent.doSmthOnStop();},
onTicked: (int millisLeft) {
setState((){
parentStateVariable = millisLeft;
});
})
...