簡體   English   中英

只有在 Flutter 中沒有異常時才顯示加載指示器

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

我創建了一個登錄屏幕,一旦 email 和密碼得到驗證,用戶將被推送到儀表板。 所以我需要做的是,只有在沒有拋出異常時才顯示加載指示器,否則它應該顯示我在 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 更改 state。

那么下面的代碼做了什么:

  1. 最初 _isLoading 將為 false,因此它會向您顯示文本小部件。
  2. 當您點擊登錄按鈕時,它將變為 true,因此會出現循環進度指示器。
  3. 然后當 api 調用完成后,將其重置為 false,這樣我們就可以看到文本小部件了。
  4. 如果出現任何錯誤,異常會將 _isLoading 設置為 false,這樣它將成為文本小部件,並且會顯示帶有錯誤消息的對話框。

我已經采用了您的代碼,只是進行了更改檢查 bool 值的使用並根據您 state 管理需求使用它,我已經用一個簡單的 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),
                    ))
              ],
            ));
      }
    }
  }

}

讓我知道它是否有效

flutter

[英]Break out of a loading flutter

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM