仅在 Flutter 中没有异常时才显示加载指示器

Show loading indicator only if there's no exceptions in Flutter

我已经创建了一个登录屏幕,一旦电子邮件和密码得到验证,用户就会被推送到仪表板。所以我需要做的是,只有在没有抛出异常时才显示加载指示器,否则它应该显示我在 try-catch 中实现的警报。

登录按钮-

SizedBox(
                    width: MediaQuery.of(context).size.width,
                    child: TextButton(
                      onPressed: signIn,
                      style: ButtonStyle(
                        padding: MaterialStateProperty.all<EdgeInsets>(
                          const EdgeInsets.fromLTRB(0, 20, 0, 20),
                        ),
                        shape:
                            MaterialStateProperty.all<RoundedRectangleBorder>(
                                RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(30.0))),
                        backgroundColor:
                            MaterialStateProperty.all(primaryColor),
                      ),
                      child: const Text(
                        'Login',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 15,
                          fontFamily: 'InterBold',
                        ),
                      ),
                    ),
                  ),

验证class-

Future signIn() async {
    if (_key.currentState!.validate()) {
      try {
        await FirebaseAuth.instance.signInWithEmailAndPassword(
            email: emailController.text.trim(),
            password: passwordCrontroller.text.trim());

        errorMessage = '';
      } on FirebaseAuthException catch (e) {
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
                  title: const Text(
                    'Error',
                    style: TextStyle(color: mainText),
                  ),
                  content: Text(
                    e.message!,
                    style: const TextStyle(color: secondaryText),
                  ),
                  contentPadding:
                      const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 0.0),
                  backgroundColor: Colors.white,
                  actions: [
                    TextButton(
                        onPressed: () {
                          navigatorKey.currentState!.pop();
                        },
                        child: const Text(
                          'Close',
                          style: TextStyle(color: primaryColor),
                        ))
                  ],
                ));
      }
    }
  }

  String? validateEmail(String? formEmail) {
    String pattern = r'\w+@\w+\.\w+';
    RegExp regex = RegExp(pattern);

    if (formEmail == null || formEmail.isEmpty || !regex.hasMatch(formEmail)) {
      return '';
    }

    return null;
  }

  String? validatePassword(String? formPassword) {
    String pattern =
        r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#$&*~]).{6,}$';
    RegExp regex = RegExp(pattern);
    if (formPassword == null ||
        formPassword.isEmpty ||
        !regex.hasMatch(formPassword)) {
      return '';
    }
    return null;
  }
}

加载指示器-

showLoadingIndicatorDialog(BuildContext context) {
  return showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => const Center(
            child: CircularProgressIndicator(
              color: primaryColor,
            ),
          ));
}

所以你可以做的是:

声明 bool 值 _isLoading =false;

您可以使用 setstate 来更改状态。

那么下面的代码是做什么的:

  1. 最初 _isLoading 将为假,因此它会向您显示文本小部件。
  2. 当您点击登录按钮时,它将变为 true,因此会出现循环进度指示器。
  3. 然后在 api 调用完成后将其重置回 false,这样我们就可以看到文本小部件了。
  4. 如果出现任何错误,异常会将 _isLoading 设置为 false,这样它将成为文本小部件,并且会显示带有错误消息的对话框。

我已经获取了您的代码,只是进行了更改,检查 bool 值的使用并根据您的状态管理需要使用它,我已经详细说明了一个简单的 setState。

class App extends StatelessWidget {

  bool _isLoading =false;

 @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return SizedBox(
      width: MediaQuery.of(context).size.width,
      child: TextButton(
        onPressed: signIn,
        style: ButtonStyle(
          padding: MaterialStateProperty.all<EdgeInsets>(
            const EdgeInsets.fromLTRB(0, 20, 0, 20),
          ),
          shape:
          MaterialStateProperty.all<RoundedRectangleBorder>(
              RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(30.0))),
          // backgroundColor:
          // MaterialStateProperty.all(primaryColor),
        ),
        child:

        _isLoading ?
        const CircularProgressIndicator():
        const Text(
          'Login',
          style: TextStyle(
            color: Colors.white,
            fontSize: 15,
            fontFamily: 'InterBold',
          ),
        ),
      ),
    );
  }
  Future signIn() async {

    if (_key.currentState!.validate()) {
      try {

        setState({
          _isLoading =true;
        });
        await FirebaseAuth.instance.signInWithEmailAndPassword(
            email: emailController.text.trim(),
            password: passwordCrontroller.text.trim());

        errorMessage = '';
        setState({
        _isLoading =false;
        });

      } on FirebaseAuthException catch (e) {
        setState({
        _isLoading =false;
        });
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
              title: const Text(
                'Error',
                style: TextStyle(color: mainText),
              ),
              content: Text(
                e.message!,
                style: const TextStyle(color: secondaryText),
              ),
              contentPadding:
              const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 0.0),
              backgroundColor: Colors.white,
              actions: [
                TextButton(
                    onPressed: () {
                      navigatorKey.currentState!.pop();
                    },
                    child: const Text(
                      'Close',
                      style: TextStyle(color: primaryColor),
                    ))
              ],
            ));
      }
    }
  }

}

如果有效请告诉我