首页 > 解决方案 > 如何在颤振中添加全屏加载程序

问题描述

在这里,我正在尝试添加一个全屏加载器,但它不起作用,我已经完成了完整的代码,但是当我尝试添加一个全屏加载器时它不起作用。所以在这里我只想在单击登录按钮时添加全屏加载程序。在这段代码中,我已经定义了 _isLoading 变量,当它的真正加载器将被显示时。

这是我尝试过的代码。

class LoginScreen extends StatefulWidget {
  LoginScreen({Key key}) : super(key: key);

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

class _LoginScreenState extends State<LoginScreen> {
  @override
  Widget build(BuildContext context) {
    final formKey = new GlobalKey<FormState>();
    final _emailFocusNode = new FocusNode();
    final _passwordFocusNode = new FocusNode();

    String _username;
    String _password;
    bool rememberMe = false;
    bool _isLoading = false;

    @override
    void initState() {
      super.initState();
    }

    void _showErrorDialog(String message) {
      showDialog(
          barrierDismissible: false,
          context: context,
          builder: (context) => ShowErrorDialog(
                title: Text('An Error Occurred!'),
                content: Text(message),
              ));
    }

    Widget _buildUserNameField() {
      return EnsureVisibleWhenFocused(
        focusNode: _emailFocusNode,
        child: TudoEmailWidget(
          focusNode: _emailFocusNode,
          prefixIcon: Icon(Icons.email),
          labelText: AppConstantsValue.appConst['login']['email']
              ['translation'],
          validator: (val) => Validators.validateEmail(val.trim()),
          onSaved: (val) => _username = val.trim(),
          // onChanged:(val) => _username = val.trim(),
        ),
      );
    }

    Widget _buildPasswordField() {
      return EnsureVisibleWhenFocused(
        focusNode: _passwordFocusNode,
        child: TudoPasswordWidget(
          focusNode: _passwordFocusNode,
          prefixIcon: Icon(Icons.vpn_key),
          hintText: AppConstantsValue.appConst['login']['password']
              ['translation'],
          labelText: AppConstantsValue.appConst['login']['password']
              ['translation'],
          validator: Validators().validatePassword,
          onSaved: (val) => _password = val.trim(),
        ),
      );
    }

    Widget _buildLoginButton(BuildContext context, LoginViewModel loginVm) {
      return GestureDetector(
        child: TudoLoginButtonWidget.buildRoundedRectButton(
            "Log In", signInGradients, false),
        onTap: () async {
          if (!formKey.currentState.validate()) {
            // Invalid!
            return;
          }
          formKey.currentState.save();
          print("User");

          setState(() {
            _isLoading = true;
          });
          try {
            LoginRepository _loginRepository = LoginRepository();
            Map<String, dynamic> loginResponse =
                await _loginRepository.loginUser(_username, _password);
            if (loginResponse['error'] != null) {
              var errorMessage = 'Invalid email or password';
              _showErrorDialog(errorMessage);
            } else {
              LoginUser userModel = LoginUser(
                token: loginResponse['data']['loginUser']['token'],
                user: User.fromJson(
                  loginResponse['data']['loginUser']['user'],
                ),
              );
              SharedPreferences preferences =
                  await SharedPreferences.getInstance();
              preferences.setString('user', loginUserToJson(userModel));
              loginVm.loginMe(context, userModel);
            }
            setState(() {
              _isLoading = false;
            });
          } catch (error) {
            print('error');
            print(error);
            setState(() {
              _isLoading = false;
            });
            var errorMessage = 'Authentication failed';
            _showErrorDialog(errorMessage);
          }
        },
      );
    }


    Widget content(context, loginVm) {
      ProgressDialog pr =
          new ProgressDialog(context, type: ProgressDialogType.Normal);
      pr.style(message: 'Showing some progress...');
      return new SafeArea(
        top: false,
        bottom: false,
        child: Form(
          key: formKey,
          child: Scrollbar(
            child: SingleChildScrollView(
              dragStartBehavior: DragStartBehavior.down,
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: new Container(
                margin: EdgeInsets.fromLTRB(30, 100, 30, 0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    TudoLogoWidget(),
                    _buildUserNameField(),
                    SizedBox(
                      height: 20,
                    ),
                    _buildPasswordField(),

                    SizedBox(
                      height: 20.0,
                    ),
                    _buildLoginButton(context, loginVm),
                    SizedBox(
                      height: 20,
                    ),

                  ],
                ),
              ),
            ),
          ),
        ),
      );
    }

    return new WillPopScope(
      onWillPop: () =>
          SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
      child: Scaffold(
        body: Container(
          height: double.infinity,
          width: double.infinity,
          child: Stack(
            children: <Widget>[
              Background(),
              SingleChildScrollView(
                  child: StoreConnector<AppState, LoginViewModel>(
                converter: (Store<AppState> store) =>
                    LoginViewModel.fromStore(store),
                builder: (BuildContext context, LoginViewModel loginVm) =>
                    content(context, loginVm),
              )),
            ],
          ),
        ),
      ),
    );
  }
}

class LoginViewModel {
  final Function(BuildContext context, LoginUser loginUser) loginMe;
  LoginViewModel({
    this.loginMe,
  });

  static LoginViewModel fromStore(Store<AppState> store) {
    return LoginViewModel(
      loginMe: (context, loginUser) {
        store.dispatch(
          login(context, loginUser),
        );
      },
    );
  }
}

标签: flutterflutter-layoutloaderprogressflutter-dependencies

解决方案


我注意到你的构建方法中有很多嵌套的东西。你可以把它们拉出来。

例如,我认为您的 initState() 方法不会在任何时候被调用。

您需要做的是:只需从现在的位置删除该行:

  Widget build(BuildContext context) {

它像这样添加:

    @override
        Widget build(BuildContext context) {    

// YOU HAVE THIS 

          final normalLoginWidgets = WillPopScope(
            onWillPop: () =>
                SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
            child: Scaffold(
              body: Container(
                height: double.infinity,
                width: double.infinity,
                child: Stack(
                  children: <Widget>[
                    Background(),
                    SingleChildScrollView(
                        child: StoreConnector<AppState, LoginViewModel>(
                          converter: (Store<AppState> store) =>
                              LoginViewModel.fromStore(store),
                          builder: (BuildContext context, LoginViewModel loginVm) =>
                              content(context, loginVm),
                        )),
                  ],
                ),
              ),
            ),
          );

          // THIS IS NEW

          if (_isLoading) {
            return Stack(children: <Widget>[
              normalLoginWidgets,
              loadingWidget()
            ]);
          } else {
            return normalLoginWidgets;
          }
        }

推荐阅读