Как добавить полноэкранный загрузчик в флаттер - PullRequest
0 голосов
/ 10 октября 2019

Здесь я пытаюсь добавить полноэкранный загрузчик, но он не работает, я выполнил полный код, но когда я пытаюсь добавить полноэкранный загрузчик, он не будет работать. поэтому здесь я хочу просто добавить полноэкранный загрузчик, когда я нажимаю на кнопку входа в систему. в этом коде я уже определил переменную _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),
        );
      },
    );
  }
}

Ответы [ 3 ]

1 голос
/ 10 октября 2019

Я заметил, что у вас много вложенных вещей в вашем методе сборки. Вы можете вытащить их.

Я имею в виду, например, я не думаю, что ваш метод 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;
          }
        }
0 голосов
/ 10 октября 2019
void showWait(context) {
  showDialog(
      context: context,
      child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 4.0, sigmaY: 4.0),
          child: Scaffold(
            backgroundColor: Colors.transparent,
            body: Container(
              color: Colors.transparent,
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Container(
                    width: MediaQuery.of(context).size.width,
                    child: CircularProgressIndicator()
                  ),
                  Container(
                    margin: EdgeInsets.symmetric(vertical: 20),
                    child: Text(
                      "LOADING...",
                      style: TextStyle(color: Colors.white),
                    ),
                  )
                ],
              ),
            ),
          )));
}

и просто вызовите showWait (context);в вашем событии кнопки.

0 голосов
/ 10 октября 2019

Я создаю один класс для отображения / закрытия диалогового окна загрузки.
Когда вам нужно показать диалоговое окно загрузки в полноэкранном режиме, вам просто нужно вызвать этот метод.

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

class ProcessDialog {
  static ProcessDialog _instance = new ProcessDialog.internal();
  static bool _isLoading = false;
  ProcessDialog.internal();
  factory ProcessDialog() => _instance;
  static BuildContext _context;

  static void closeLoadingDialog() {
    if (_isLoading) {
      Navigator.of(_context).pop();
      _isLoading = false;
    }
  }

  static void showLoadingDialog(BuildContext context) async {
    _context = context;
    _isLoading = true;
    await showDialog(
        context: _context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return SimpleDialog(
            elevation: 0.0,
            backgroundColor: Colors.transparent,
            children: <Widget>[
              Center(
                child: CircularProgressIndicator(
                  valueColor:
                      AlwaysStoppedAnimation<Color>(ColorUtils.primaryColor),
                ),
              )
            ],
          );
        });
  }

}
...