Flutter - Create a countdown widget Flutter - Create a countdown widget flutter flutter

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.

countdown

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


based on @raju-bitter answer, alternative to use async/await on countdown stream

  void countdown() async {    cd = new CountDown(new Duration(seconds:4));    await for (var v in cd.stream) {      setState(() => val = v.inSeconds);    }  }