CircularProgressIndicator only shows one time

Viewed 71

I want that everytime the user clicks on the login button to show a CircularProgressIndicator instead of the button, while the data is being fetched from the API and after fetching is done, show the login button again or go to the main page based on the fetched data. But it only shows for the first time and with the next click it is not shown and it only shows the button!

here is my code:

import 'package:flutter/material.dart';
import 'package:news/src/blocs/latest_news_provider.dart';

import 'home_screen.dart';

class Chart extends StatefulWidget {
  @override
  _State createState() => _State();
}

class _State extends State<Chart> {
  TextEditingController nameController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  bool hasErr = false;
  late String errTxt;
  bool isButtonPressed = false;

  @override
  Widget build(BuildContext context) {
    final bloc = LatestNewsProvider.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Crypto'),
        backgroundColor: Colors.purple[700],
      ),
      body: StreamBuilder(
          stream: bloc.loginStream,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              isButtonPressed = false;
              WidgetsBinding.instance!.addPostFrameCallback((_) {
                Navigator.pushReplacement(
                    context, MaterialPageRoute(builder: (_) => HomeScreen()));
              });
            } else if (snapshot.hasError) {
              isButtonPressed = false;
              hasErr = true;
              errTxt = snapshot.error.toString();
            }
            return Padding(
                padding: EdgeInsets.all(10),
                child: ListView(
                  children: <Widget>[
                    Container(
                        alignment: Alignment.center,
                        padding: EdgeInsets.all(10),
                        child: Text(
                          'Nobitex',
                          style: TextStyle(
                              color: Colors.purple[700],
                              fontWeight: FontWeight.w500,
                              fontSize: 30),
                        )),
                    Container(
                      padding: EdgeInsets.all(10),
                      child: TextField(
                        controller: nameController,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          labelText: 'Username',
                        ),
                      ),
                    ),
                    Container(
                      padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
                      child: TextField(
                        obscureText: true,
                        controller: passwordController,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          labelText: 'Password',
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    isButtonPressed
                        ? Center(
                            child: CircularProgressIndicator(
                            color: Colors.purple[700],
                          ))
                        : Container(
                            height: 50,
                            padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                  primary: Colors.purple[700]),
                              child: Text('Login'),
                              onPressed: () {
                                setState(() {
                                  isButtonPressed = true;
                                  hasErr = false;
                                });
                                bloc.login(nameController.text,
                                    passwordController.text);
                              },
                            )),
                    hasErr == true
                        ? Container(
                            margin: EdgeInsets.only(top: 10),
                            child: Center(
                                child: Text(
                              errTxt.toString(),
                              style: TextStyle(
                                color: Colors.red,
                                fontWeight: FontWeight.bold,
                              ),
                            )))
                        : Container()
                  ],
                ));
          }),
    );
  }
}
1 Answers

If you are using bloc, then you should also have a class to hold the states. When you click on the button to create an login event, update the states of the bloc according to your api response.

Related