Flutter setState() not triggering re-build

Issue

I have a login page, and I want to change the button into a CupertinoActivityIndicator when it’s tapped. Here’s my code :

class AuthRegister extends StatefulWidget {
  AuthRegister({Key key, this.authenticator}): super(key: key);

  final FirebaseAuth authenticator;

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

class _AuthRegisterState extends State<AuthRegister> {

  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  bool _loading = false;


  void _register(context) async {
    setState(() {
      _loading = true;
    });
    try {
      sleep(const Duration(seconds: 2));
      throw ("Debug");
    } catch (e) {
      print(e);
      setState(() {
        _loading = false;
      });
      Fluttertoast.showToast(msg: e);
    }
  }

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    // I even tried this and it still fails
    // if (_loading) {
    //   return CupertinoActivityIndicator();
    // }

    return CupertinoPageScaffold(
      child: Form(
        key: _formKey,
        child: ListView(children: [
          Text('CREATE AN ACCOUNT'),
          Padding(
              padding: EdgeInsets.symmetric(horizontal: 20),
              child: MyInput(type: 'email', controller: _emailController)),
          Padding(
              padding: EdgeInsets.symmetric(horizontal: 20),
              child: MyInput(type: 'password', controller: _passwordController)),
          Padding(
            padding: EdgeInsets.only(top: 36, bottom: 14, left: 45, right: 45),

            // HERE ---- \/ \/ ----

            child: (_loading) ?
              CupertinoActivityIndicator() :
              FullButton(
                onPressed: () {
                  // I tried doing setState here but it didn't work
                  // setState(() {
                  //   _loading = true;
                  // });
                  _register(context);
                },
                text: 'CREATE AN ACCOUNT',
                fillColor: true),
            ),

          // /HERE ---- /\ /\ ----

          Center(
            child: Text(
              'FORGOT PASSWORD?',
              style: TextStyle(
                  color: Color.fromRGBO(0xEE, 0x56, 0x42, 1.0),
                  fontFamily: 'Montserrat',
                  fontSize: 12),
            ),
          ),
        ]),
      ),
    );
  }
}

As you can see, I have tried different ways. I’ve been searching the web and everywhere I look, it seemd that I’m doing everything correctly. All I could find among people with the same problem as me were cases where the boolean variable used to perform the condition was declared locally in some function or people using StatelessWidgets, etc…

What am I doing wrong ?

Solution

Replace

sleep(const Duration(seconds: 2));

with

Future.delayed(Duration(seconds: 2)).then((_) {
  throw ("Debug");
});

Answered By – Teddichiiwa

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *