Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a Count down Timer within and Alertbox in flutter

i have a Flutter app which should show a counting down timer in an alert box for Phone code confirming (i need this timer to resend the code to my user when 60 second is up) , i start timer when i click on Confirm Button , but the problem is that the timer is not showing that he's going down he stills with a fixed value.

here is my alert box

Alert Box with timer NOT SHOWING COUNT DOWN

here is my timer Function :

int _counter = 60;
   Timer _timer;
     void _startTimer(){
_counter = 60;
if(_timer != null){
  _timer.cancel();
}
_timer = Timer.periodic(Duration(seconds: 1), (timer){
  setState(() {
    (_counter > 0) ? _counter-- : _timer.cancel();
  });
});
}

here is my alert Box code :

void alertD(BuildContext ctx) {
var alert = AlertDialog(
    // title: Center(child:Text('Enter Code')),
    shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(20.0))),
    backgroundColor: Colors.grey[100],
    elevation: 0.0,
    content: Container(
      height: 215,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Padding(
              padding: const EdgeInsets.only(
                  top: 10, left: 10, right: 10, bottom: 15),
              child: Text(
                'Enter Code',
                style: TextStyle(
                  color: Colors.green[800],
                  fontWeight: FontWeight.bold,
                  fontSize: 16
                ),
              )),
          Container(
            height: 70,
            width: 180,
            child: TextFormField(
              style: TextStyle(fontSize: 20,fontWeight: FontWeight.bold),
              textAlign: TextAlign.center,
              decoration: InputDecoration(
                enabledBorder: OutlineInputBorder(
                    borderSide:
                        BorderSide(color: Colors.green, width: 0.0)),
              ),
              keyboardType: TextInputType.number,
              maxLength: 10,
            ),
          ),
          SizedBox(
            height: 1,
          ),
          Text('00:$_counter'),
          SizedBox(height: 15,)
          ,
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              ClipRRect(
                borderRadius: BorderRadius.circular(25),
                child: Material(
                  child: InkWell(
                    onTap: () {
                      Navigator.of(ctx).pushNamed(SignUpScreenSecond.routeName);
                    },
                    child: Container(
                      width: 100,
                      height: 50,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                        gradient: LinearGradient(
                            colors: [
                              Colors.green,
                              Colors.grey,
                            ],
                            begin: Alignment.topLeft,
                            end: Alignment.bottomRight),
                      ),
                      child: Center(
                          child: Text(
                        'Validate',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 16,
                            fontWeight: FontWeight.bold),
                      )),
                    ),
                  ),
                ),
              ),
              ClipRRect(
                borderRadius: BorderRadius.circular(25),
                child: Material(
                  child: InkWell(
                    onTap: () {},
                    child: Container(
                      width: 100,
                      height: 50,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                        gradient: LinearGradient(
                            colors: [
                              Colors.grey,
                              Colors.green,
                            ],
                            begin: Alignment.topLeft,
                            end: Alignment.bottomRight),
                      ),
                      child: Center(
                          child: Text(
                        'Resend',
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 16,
                            fontWeight: FontWeight.bold),
                      )),
                    ),
                  ),
                ),
              )
            ],
          ), //new column child
        ],
      ),
    ));
showDialog(
    context: ctx,
    builder: (BuildContext c) {
      return alert;
    });
 }

that's how i'm calling my alert dialog and my timer when i click Confirm Button :

onTap: () {
           _startTimer;
           alertD(context);
              },
like image 381
Said Pc Avatar asked May 04 '20 14:05

Said Pc


People also ask

How do you show countdown timer in flutter?

Steps to add countdown timer in Flutter: Step 1: Make sure you have a StatefulWidget class. Step 2: Add the timer and duration variable. Step 3: Add a method called startTimer() to start the timer. Step 4: Add a method called stopTimer() to stop the timer.

How do I show the alert box in flutter?

dart file. To show an alert, you must have to call showDialog() function, which contains the context and itemBuilder function. The itemBuilder function returns an object of type dialog, the AlertDialog. Now, run the app, it will give the following output.

How do you dismiss dialog automatically in flutter?

To Dismiss Dialog user needs to make use of an inbuilt class like showDialog. The dialog route created by this method is pushed to the root navigator. If the application has multiple Navigator objects. It may be necessary to call Navigator.


1 Answers

You can copy paste run full code below
You can use StreamBuilder and StreamController
AlertDialog content continually receive stream int from Timer

code snippet

StreamController<int> _events;

  @override
  initState() {
    super.initState();
    _events = new StreamController<int>();
    _events.add(60);
  }

...
 _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      (_counter > 0) ? _counter-- : _timer.cancel();
      print(_counter);
      _events.add(_counter);
    });

...
content: StreamBuilder<int>(
            stream: _events.stream,
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) {

      ...
      Text('00:${snapshot.data.toString()}'),     

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  StreamController<int> _events;

  @override
  initState() {
    super.initState();
    _events = new StreamController<int>();
    _events.add(60);
  }

  Timer _timer;
  void _startTimer() {
    _counter = 60;
    if (_timer != null) {
      _timer.cancel();
    }
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      //setState(() {
      (_counter > 0) ? _counter-- : _timer.cancel();
      //});
      print(_counter);
      _events.add(_counter);
    });
  }

  void alertD(BuildContext ctx) {
    var alert = AlertDialog(
        // title: Center(child:Text('Enter Code')),
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(20.0))),
        backgroundColor: Colors.grey[100],
        elevation: 0.0,
        content: StreamBuilder<int>(
            stream: _events.stream,
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
              print(snapshot.data.toString());
              return Container(
                height: 215,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Padding(
                        padding: const EdgeInsets.only(
                            top: 10, left: 10, right: 10, bottom: 15),
                        child: Text(
                          'Enter Code',
                          style: TextStyle(
                              color: Colors.green[800],
                              fontWeight: FontWeight.bold,
                              fontSize: 16),
                        )),
                    Container(
                      height: 70,
                      width: 180,
                      child: TextFormField(
                        style: TextStyle(
                            fontSize: 20, fontWeight: FontWeight.bold),
                        textAlign: TextAlign.center,
                        decoration: InputDecoration(
                          enabledBorder: OutlineInputBorder(
                              borderSide:
                                  BorderSide(color: Colors.green, width: 0.0)),
                        ),
                        keyboardType: TextInputType.number,
                        maxLength: 10,
                      ),
                    ),
                    SizedBox(
                      height: 1,
                    ),
                    Text('00:${snapshot.data.toString()}'),
                    SizedBox(
                      height: 15,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Material(
                            child: InkWell(
                              onTap: () {
                                //Navigator.of(ctx).pushNamed(SignUpScreenSecond.routeName);
                              },
                              child: Container(
                                width: 100,
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  gradient: LinearGradient(
                                      colors: [
                                        Colors.green,
                                        Colors.grey,
                                      ],
                                      begin: Alignment.topLeft,
                                      end: Alignment.bottomRight),
                                ),
                                child: Center(
                                    child: Text(
                                  'Validate',
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 16,
                                      fontWeight: FontWeight.bold),
                                )),
                              ),
                            ),
                          ),
                        ),
                        ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Material(
                            child: InkWell(
                              onTap: () {},
                              child: Container(
                                width: 100,
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  gradient: LinearGradient(
                                      colors: [
                                        Colors.grey,
                                        Colors.green,
                                      ],
                                      begin: Alignment.topLeft,
                                      end: Alignment.bottomRight),
                                ),
                                child: Center(
                                    child: Text(
                                  'Resend',
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 16,
                                      fontWeight: FontWeight.bold),
                                )),
                              ),
                            ),
                          ),
                        )
                      ],
                    ), //new column child
                  ],
                ),
              );
            }));
    showDialog(
        context: ctx,
        builder: (BuildContext c) {
          return alert;
        });
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
                onPressed: () {
                  _startTimer();
                  alertD(context);
                },
                child: Text('Click')),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
like image 101
chunhunghan Avatar answered Oct 17 '22 07:10

chunhunghan