如何在异步调用函数时显示加载器?

问题描述 投票:0回答:2

我正在异步调用一个函数,以使用 Firebase 使用电话号码注册用户。我想在拨打电话时显示

CircularProgressIndicator
,因为处理请求所需的时间很少。为此,我使用了状态变量
isLoading
。每当我调用异步函数时,我都会将
isLoading 
设置为
true
。在我的小部件树中,我有一个
if 
条件,当该条件为真时,会显示
CircularProgressIndicator
。但它没有显示加载程序。请帮助我理解这段代码的控制流程。

另外,我可以在这里使用 Future builder 吗?

我最初设置了

isLoading = false

if (isLoading)
              const Center(
                child: CircularProgressIndicator(),
              ),
            LoginButton(
              loginText: StaticText.sendCode,
              onTapButton: () async {
                setState(() {
                  isLoading = true;
                });

                // onClickSendCode calls another function asynchronously

                await AuthFunctions.onClickSendCode(
                  mobileController: mobileController,
                  context: context,
                );

                setState(() {
                  isLoading = false;
                });
              },
            ),
            if (isLoading)
              const Center(
                child: CircularProgressIndicator(),
              ),

这是我的 onClickSendCode 函数:

  // SENDING OTP
  static Future<void> onClickSendCode({
    required TextEditingController mobileController,
    required BuildContext context,
  }) async {
    if (mobileController.text.length != 10) {
      failureBar(StaticText.invalidPhoneNo, context);
      return;
    }
    FocusManager.instance.primaryFocus?.unfocus();

    print('circular');
    const CircularProgressIndicator();

    await AuthService().registerUserWithPhone(
      mobileController.text,
      context,
    );
  }

这是用电话注册用户:

  //  OTP
  Future<void> registerUserWithPhone(
    String mobile,
    BuildContext context,
  ) async {
    final auth = FirebaseAuth.instance;
    // print(mobile);
    await auth.verifyPhoneNumber(
      phoneNumber: '+91$mobile',
      verificationCompleted: (PhoneAuthCredential credential) {},
      verificationFailed: (FirebaseAuthException e) {},
      codeSent: (String verificationId, int? forceResendingToken) {
        Navigator.pushNamed(
          context,
          NamedRoutes.verifyCode,
          arguments: verificationId,
        );
      },
      codeAutoRetrievalTimeout: (String verificationId) {},
      timeout: const Duration(
        seconds: 120,
      ),
    );
  }
}

我尝试使用Future builder,但它也不起作用。我无法理解 setState 方法如何调用 build 方法。请帮助我。

flutter firebase dart asynchronous
2个回答
0
投票

在这种情况下,您可以使用 valueListenable 小部件来通过执行类似的操作来显示或不显示微调器。

ValueListenableBuilder<bool>(
  valueListenable: isLoading,
  child: child, //Widgets that are always shown
  builder: (context, isLoading, child) {
   //The widgets you want to display when isLoading == true
  })
);

在你的情况下我会走这条路。

此外,您可以实现 BLOC 来处理小部件的状态。这是处理这种情况的一种更复杂的方法,但最终更稳健。


0
投票

我不知道这背后的原因或解释,但这通常对我有用:

isLoading 
  ? const Center(child: CircularProgressIndicator())
  : LoginButton(...);
© www.soinside.com 2019 - 2024. All rights reserved.