Flutter - Create a countdown widget
It sounds like you are trying to show an animated text widget that changes over time. I would use an AnimatedWidget
with a StepTween
to ensure that the countdown only shows integer values.
import 'package:flutter/material.dart';void main() { runApp(new MaterialApp( home: new MyApp(), ));}class Countdown extends AnimatedWidget { Countdown({ Key key, this.animation }) : super(key: key, listenable: animation); Animation<int> animation; @override build(BuildContext context){ return new Text( animation.value.toString(), style: new TextStyle(fontSize: 150.0), ); }}class MyApp extends StatefulWidget { State createState() => new _MyAppState();}class _MyAppState extends State<MyApp> with TickerProviderStateMixin { AnimationController _controller; static const int kStartValue = 4; @override void initState() { super.initState(); _controller = new AnimationController( vsync: this, duration: new Duration(seconds: kStartValue), ); } @override Widget build(BuildContext context) { return new Scaffold( floatingActionButton: new FloatingActionButton( child: new Icon(Icons.play_arrow), onPressed: () => _controller.forward(from: 0.0), ), body: new Container( child: new Center( child: new Countdown( animation: new StepTween( begin: kStartValue, end: 0, ).animate(_controller), ), ), ), ); }}
The countdown()
method should be called from the initState()
method of the State
object.
class _CountdownState extends State<CountdownWidget> { int val = 3; CountDown cd; @override void initState() { super.initState(); countdown(); }...
Description of initState()
from the Flutter docs:
The framework calls initState. Subclasses of State should override initState to perform one-time initialization that depends on the BuildContext or the widget, which are available as the context and widget properties, respectively, when the initState method is called.
Here is a full working example:
import 'dart:async';import 'package:flutter/material.dart';import 'package:countdown/countdown.dart';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Countdown Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(), ); }}class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return new CountdownWidget(); }}class _CountdownState extends State<CountdownWidget> { int val = 3; CountDown cd; @override void initState() { super.initState(); countdown(); } void countdown(){ print("countdown() called"); cd = new CountDown(new Duration(seconds: 4)); StreamSubscription sub = cd.stream.listen(null); sub.onDone(() { print("Done"); }); sub.onData((Duration d) { if (val == d.inSeconds) return; print("onData: d.inSeconds=${d.inSeconds}"); setState((){ val = d.inSeconds; }); }); } @override build(BuildContext context){ return new Scaffold( body: new Container( child: new Center( child: new Text(val.toString(), style: new TextStyle(fontSize: 150.0)), ), ), ); }}class CountdownWidget extends StatefulWidget { @override _CountdownState createState() => new _CountdownState();}