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