Flutter не восстанавливает виджет после вызова setState()

#flutter #dart

#flutter #dart

Вопрос:

В processForm() функции виджет должен быть собран заново и показывать индикатор хода загрузки, но работает неправильно, что я делаю не так?

Значение для isLoading обновляется, но виджет не обновляется

Это функция:

 processForm() {
      if (formKey.currentState.validate()) {
        setState(() {
          isLoading = true;
        });
        auth.signUpWithEmailAndPassword(
            uiEmailController.text, uiPasswordController.text);
      }
    }
  

Это весь код для виджета:

 class SignUp extends StatefulWidget {
  @override
  _SignUpState createState() => _SignUpState();
}

class _SignUpState extends State<SignUp> {
  @override
  Widget build(BuildContext context) {
    bool isLoading = false;
    AuthMethods auth = AuthMethods();
    final formKey = GlobalKey<FormState>();
    TextEditingController uiUsernameController = TextEditingController();
    TextEditingController uiEmailController = TextEditingController();
    TextEditingController uiPasswordController = TextEditingController();
    processForm() {
      if (formKey.currentState.validate()) {
        setState(() {
          isLoading = true;
        });
        auth.signUpWithEmailAndPassword(
            uiEmailController.text, uiPasswordController.text);
      }
    }

    return Scaffold(
      appBar: myAppBar(),
      body: isLoading
          ? Center(
              child: CircularProgressIndicator(),
            )
          : Center(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.all(25.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text(
                        "Sign Up",
                        style: TextStyle(color: Colors.white, fontSize: 20),
                      ),
                      SizedBox(
                        height: 10,
                      ),
                      Form(
                        key: formKey,
                        child: Column(
                          children: [
                            TextFormField(
                              validator: (username) {
                                return username.length > 5
                                    ? null
                                    : "Invalid Username";
                              },
                              controller: uiUsernameController,
                              style: myInputTextStyle(),
                              decoration: myTextFieldDecoration("Username"),
                            ),
                            TextFormField(
                              validator: (mail) {
                                return RegExp(
                                            r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%amp;'* -/=?^_`{|}~] @[a-zA-Z0-9] .[a-zA-Z] ")
                                        .hasMatch(mail)
                                    ? null
                                    : "Not a valid Email Address";
                              },
                              controller: uiEmailController,
                              style: myInputTextStyle(),
                              decoration: myTextFieldDecoration("Email"),
                            ),
                            TextFormField(
                              validator: (password) {
                                return password.length >= 6
                                    ? null
                                    : "password too short";
                              },
                              controller: uiPasswordController,
                              style: myInputTextStyle(),
                              obscureText: true,
                              decoration: myTextFieldDecoration("Password"),
                            ),
                          ],
                        ),
                      ),
                      SizedBox(
                        height: 20,
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: [
                              GestureDetector(
                                onTap: () {
                                  Navigator.pushReplacementNamed(
                                      context, '/SignIn');
                                },
                                child: Text(
                                  "Already have an account?",
                                  style: TextStyle(color: Colors.white),
                                ),
                              ),
                              SizedBox(
                                height: 5,
                              ),
                              FlatButton(
                                  shape: RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(20)),
                                  color: Colors.white,
                                  onPressed: () {
                                    processForm();
                                  },
                                  textColor: Colors.indigoAccent,
                                  child: Text("Sign up")),
                              FlatButton(
                                  shape: RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(20)),
                                  color: Colors.white,
                                  onPressed: () {},
                                  textColor: Colors.indigoAccent,
                                  child: Text("Sign up with Google")),
                            ],
                          ),
                        ],`enter code here`
                      ),
                    ],
                  ),
                ),
              ),
            ),
    );
  }


  

Комментарии:

1. Вы уверены, что это validate() вернуло значение true?

2. Да, он обновляет isLoading , и я получаю ожидаемый результат в консоли, просто пользовательский интерфейс его не показывает

Ответ №1:

Проблема в том, что вы разместили свои переменные внутри build .
Не делайте этого и вместо этого поместите как свойство State :

 class _SignUpState extends State<SignUp> {
  bool isLoading = false;
  AuthMethods auth = AuthMethods();
  final formKey = GlobalKey<FormState>();
  TextEditingController uiUsernameController = TextEditingController();
  TextEditingController uiEmailController = TextEditingController();
  TextEditingController uiPasswordController = TextEditingController();


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: myAppBar(),
      body: isLoading
          ? Center(
              child: CircularProgressIndicator(),
            )
          : Center(...),
    );
  }
}
  

Комментарии:

1. Большое спасибо! Я полностью упустил это из виду,