flutter - 如何在颤振中添加全屏加载程序
问题描述
在这里,我正在尝试添加一个全屏加载器,但它不起作用,我已经完成了完整的代码,但是当我尝试添加一个全屏加载器时它不起作用。所以在这里我只想在单击登录按钮时添加全屏加载程序。在这段代码中,我已经定义了 _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),
);
},
);
}
}
解决方案
我注意到你的构建方法中有很多嵌套的东西。你可以把它们拉出来。
例如,我认为您的 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;
}
}
推荐阅读
- pip - 使用 pip install 安装 Cartopy 但缺少 Proj 版本至少 4.9.0
- java - SOAP Web 服务 - 无法从 XSD 生成类
- rust - 可变借用固定结构的两个字段
- asp.net - microsoft/aspnet:4.6.2 Windows 容器中存在 web.config 时出现错误 500
- laravel - Laravel 5.7 上的分页问题
- sas - proc 逻辑输出拟合模型预测 1 还是 0
- python - 操作后查找并替换正则表达式术语?
- python - 在heroku上部署geodjango的问题
- python - Python heroku sqlite3 现有表不存在
- node.js - 收到承诺
而不是价值