How can I do to put the value passed in the construction, to make a timer that rounds to the first decimal and shows at the child text of my RaisedButton? I've tried but without luck. I manage to make work the callback function with a simple Timer but no periodic and with no update of value in real time in the text...
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),
),
),
);
}
}
Here is my Timer widget, not related to the Question but may help someone.
import 'dart:async';
import 'package:flutter/material.dart';
class OtpTimer extends StatefulWidget {
@override
_OtpTimerState createState() => _OtpTimerState();
}
class _OtpTimerState extends State<OtpTimer> {
final interval = const Duration(seconds: 1);
final int timerMaxSeconds = 60;
int currentSeconds = 0;
String get timerText =>
'${((timerMaxSeconds - currentSeconds) ~/ 60).toString().padLeft(2, '0')}: ${((timerMaxSeconds - currentSeconds) % 60).toString().padLeft(2, '0')}';
startTimeout([int milliseconds]) {
var duration = interval;
Timer.periodic(duration, (timer) {
setState(() {
print(timer.tick);
currentSeconds = timer.tick;
if (timer.tick >= timerMaxSeconds) timer.cancel();
});
});
}
@override
void initState() {
startTimeout();
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.timer),
SizedBox(
width: 5,
),
Text(timerText)
],
);
}
}
You will get something like this
I have created a Generic Timer Widget which can be used to display any kind of timer and its flexible as well.
This Widget takes following properties
hh mm ss
string like 01 hours: 20 minutes: 45 seconds
you can provide a default formatter ( formatHHMMSS
) in case you don't want to supply it from every place.
// provide implementation for this - formatHHMMSS(duration.inSeconds);
or use below one which I have provided.
import 'package:flutter/material.dart';
class CountDownTimer extends StatefulWidget {
const CountDownTimer({
Key key,
int secondsRemaining,
this.countDownTimerStyle,
this.whenTimeExpires,
this.countDownFormatter,
}) : secondsRemaining = secondsRemaining,
super(key: key);
final int secondsRemaining;
final Function whenTimeExpires;
final Function countDownFormatter;
final TextStyle countDownTimerStyle;
State createState() => new _CountDownTimerState();
}
class _CountDownTimerState extends State<CountDownTimer>
with TickerProviderStateMixin {
AnimationController _controller;
Duration duration;
String get timerDisplayString {
Duration duration = _controller.duration * _controller.value;
return widget.countDownFormatter != null
? widget.countDownFormatter(duration.inSeconds)
: formatHHMMSS(duration.inSeconds);
// In case user doesn't provide formatter use the default one
// for that create a method which will be called formatHHMMSS or whatever you like
}
@override
void initState() {
super.initState();
duration = new Duration(seconds: widget.secondsRemaining);
_controller = new AnimationController(
vsync: this,
duration: duration,
);
_controller.reverse(from: widget.secondsRemaining.toDouble());
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {
widget.whenTimeExpires();
}
});
}
@override
void didUpdateWidget(CountDownTimer oldWidget) {
if (widget.secondsRemaining != oldWidget.secondsRemaining) {
setState(() {
duration = new Duration(seconds: widget.secondsRemaining);
_controller.dispose();
_controller = new AnimationController(
vsync: this,
duration: duration,
);
_controller.reverse(from: widget.secondsRemaining.toDouble());
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
widget.whenTimeExpires();
} else if (status == AnimationStatus.dismissed) {
print("Animation Complete");
}
});
});
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Center(
child: AnimatedBuilder(
animation: _controller,
builder: (_, Widget child) {
return Text(
timerDisplayString,
style: widget.countDownTimerStyle,
);
}));
}
}
Usage:
Container(
width: 60.0,
padding: EdgeInsets.only(top: 3.0, right: 4.0),
child: CountDownTimer(
secondsRemaining: 30,
whenTimeExpires: () {
setState(() {
hasTimerStopped = true;
});
},
countDownStyle: TextStyle(
color: Color(0XFFf5a623),
fontSize: 17.0,
height: 1.2),
),
)
example for formatHHMMSS:
String formatHHMMSS(int seconds) {
int hours = (seconds / 3600).truncate();
seconds = (seconds % 3600).truncate();
int minutes = (seconds / 60).truncate();
String hoursStr = (hours).toString().padLeft(2, '0');
String minutesStr = (minutes).toString().padLeft(2, '0');
String secondsStr = (seconds % 60).toString().padLeft(2, '0');
if (hours == 0) {
return "$minutesStr:$secondsStr";
}
return "$hoursStr:$minutesStr:$secondsStr";
}
If all you need is a simple countdown timer, this is a good alternative instead of installing a package. Happy coding!
countDownTimer() async {
int timerCount;
for (int x = 5; x > 0; x--) {
await Future.delayed(Duration(seconds: 1)).then((_) {
setState(() {
timerCount -= 1;
});
});
}
}
Countdown timer in one line
CountdownTimer(Duration(seconds: 5), Duration(seconds: 1)).listen((data){
})..onData((data){
print('data $data');
})..onDone((){
print('onDone.........');
});
doesnt directly answer your question. But helpful for those who want to start something after some time.
Future.delayed(Duration(seconds: 1), () {
print('yo hey');
});
I'm using https://pub.dev/packages/flutter_countdown_timer
dependencies: flutter_countdown_timer: ^1.0.0
$ flutter pub get
CountdownTimer(endTime: 1594829147719)
1594829147719 is your timestamp in milliseconds
Little late to the party but why don't you guys try animation.No I am not telling you to manage animation controllers and disposing them off and all that stuff.theres a built-in widget for that called TweenAnimationBuilder.You can animate between values of any type,heres an example with a Duration class
TweenAnimationBuilder<Duration>(
duration: Duration(minutes: 3),
tween: Tween(begin: Duration(minutes: 3), end: Duration.zero),
onEnd: () {
print('Timer ended');
},
builder: (BuildContext context, Duration value, Widget child) {
final minutes = value.inMinutes;
final seconds = value.inSeconds % 60;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Text('$minutes:$seconds',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 30)));
}),
and You also get onEnd call back which notifies you when the animation completes;
here's the output
You can use this plugin timer_builder
timer_builder widget that rebuilds itself on scheduled, periodic, or dynamically generated time events.
Examples
Periodic rebuild
import 'package:timer_builder/timer_builder.dart';
class ClockWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TimerBuilder.periodic(Duration(seconds: 1),
builder: (context) {
return Text("${DateTime.now()}");
}
);
}
}
Rebuild on a schedule
import 'package:timer_builder/timer_builder.dart';
class StatusIndicator extends StatelessWidget {
final DateTime startTime;
final DateTime endTime;
StatusIndicator(this.startTime, this.endTime);
@override
Widget build(BuildContext context) {
return TimerBuilder.scheduled([startTime, endTime],
builder: (context) {
final now = DateTime.now();
final started = now.compareTo(startTime) >= 0;
final ended = now.compareTo(endTime) >= 0;
return Text(started ? ended ? "Ended": "Started": "Not Started");
}
);
}
}
Source: Stackoverflow.com