仅在 Flutter 中没有异常时才显示加载指示器
Show loading indicator only if there's no exceptions in Flutter
我已经创建了一个登录屏幕,一旦电子邮件和密码得到验证,用户就会被推送到仪表板。所以我需要做的是,只有在没有抛出异常时才显示加载指示器,否则它应该显示我在 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 来更改状态。
那么下面的代码是做什么的:
- 最初 _isLoading 将为假,因此它会向您显示文本小部件。
- 当您点击登录按钮时,它将变为 true,因此会出现循环进度指示器。
- 然后在 api 调用完成后将其重置回 false,这样我们就可以看到文本小部件了。
- 如果出现任何错误,异常会将 _isLoading 设置为 false,这样它将成为文本小部件,并且会显示带有错误消息的对话框。
我已经获取了您的代码,只是进行了更改,检查 bool 值的使用并根据您的状态管理需要使用它,我已经详细说明了一个简单的 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),
))
],
));
}
}
}
}
如果有效请告诉我
我已经创建了一个登录屏幕,一旦电子邮件和密码得到验证,用户就会被推送到仪表板。所以我需要做的是,只有在没有抛出异常时才显示加载指示器,否则它应该显示我在 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 来更改状态。
那么下面的代码是做什么的:
- 最初 _isLoading 将为假,因此它会向您显示文本小部件。
- 当您点击登录按钮时,它将变为 true,因此会出现循环进度指示器。
- 然后在 api 调用完成后将其重置回 false,这样我们就可以看到文本小部件了。
- 如果出现任何错误,异常会将 _isLoading 设置为 false,这样它将成为文本小部件,并且会显示带有错误消息的对话框。
我已经获取了您的代码,只是进行了更改,检查 bool 值的使用并根据您的状态管理需要使用它,我已经详细说明了一个简单的 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),
))
],
));
}
}
}
}
如果有效请告诉我