我在 Flutter 中遇到了这个奇怪的问题。我使用“Provider”进行状态管理,在帮助程序类中一切都很好,我正在发送请求并且收到响应,没有任何问题。问题发生在按钮事件处理程序中。我第一次单击该按钮时几乎没有任何反应,当我第二次单击该按钮时,它会与 API 对话并获取数据。另一个问题是:当我输入正确的数据并将它们发送到 API 时,紧接着我输入了错误的凭据,应用程序告诉我我已经输入了正确的凭据,就好像我正在处理之前的同一个对象一样。 这是我的前端部分代码:
class _LoginPageState extends State<LoginPage> {
String? myError;
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
TextEditingController userNameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
return Directionality(
textDirection: TextDirection.rtl,
child: Consumer<PicoProvider>(
builder: (context, prov, child) => SafeArea(
child: Scaffold(
backgroundColor: CustomColors.scaffoldDark,
body: Padding(
padding: const EdgeInsets.all(100),
child: SingleChildScrollView(
child: Container(
width: screenWidth,
child: Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3),
),
]),
child: Image.asset(
'assets/images/main_logo.jpeg',
height: 300,
),
),
const SizedBox(height: 20),
CTextField(
label: 'اسم المسخدم',
icon: Ionicons.person,
isObsecured: false,
controller: userNameController),
const SizedBox(height: 20),
CTextField(
label: 'كلمة المرور',
icon: Ionicons.lock_closed,
isObsecured: true,
controller: passwordController,
onSubmitted: () {
prov.websiteLogin(userNameController.text,
passwordController.text);
}),
ElevatedButton(
onPressed: () {
prov.websiteLogin(userNameController.text,
passwordController.text);
prov.errorText!.isNotEmpty
? giveMeDialog(
context, 'hello', 'not found', 'error')
: giveMeDialog(context, 'hello',
'you are logged', 'success');
},
child: const Text('Click')),
const SizedBox(height: 20),
prov.isLoading
? const CircularProgressIndicator()
: const SizedBox(),
Text('${prov.errorText}')
],
),
),
),
),
),
),
),
),
);
}
Future<void> giveMeDialog(
BuildContext context, String title, String message, String icon) {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(title),
content: Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: [
Text(
message,
style: const TextStyle(fontSize: 30),
),
Lottie.asset('assets/animations/${icon}_animation.json'),
],
),
),
);
},
);
}
}
这是我的后端部分代码:
class PicoProvider extends ChangeNotifier {
String baseURL = 'http://111.11.11.111:1111';
bool _isLoading = false;
bool get isLoading => _isLoading;
User? _user = User();
User? get user => _user;
String? _errorText;
String? get errorText => _errorText;
Future<void> websiteLogin(String userName, String password) async {
try {
String endPoint =
'$baseURL/PicoLogin?UserName=$userName&Password=$password';
_isLoading = true;
notifyListeners();
var response = await get(Uri.parse(endPoint), headers: {
"content-type": "application/json",
"Access-Control-Allow-Origin": "*",
});
if (response.statusCode == 200) {
_user = User.fromJson(jsonDecode(response.body));
_errorText = '';
} else {
_errorText = 'User Not Found';
}
_isLoading = false;
notifyListeners();
} catch (e) {
_errorText = e.toString();
notifyListeners();
print('Error: ${e.toString()}');
}
}
}
您的问题在这里
ElevatedButton(
onPressed: () {
prov.websiteLogin(userNameController.text,
passwordController.text);
prov.errorText!.isNotEmpty
? giveMeDialog(
context, 'hello', 'not found', 'error')
: giveMeDialog(context, 'hello',
'you are logged', 'success');
},
prov.websiteLogin(..
是一个 async
函数,prov.errorText
只会在一段时间后更新。因此,在您的代码中,您不会等待 websiteLogin
完成并尝试立即显示对话框。因此它总是给出先前执行的结果。
快速非推荐修复:在
websiteLogin
中添加
onPressed
的等待
ElevatedButton(
onPressed: () async {
await prov.websiteLogin(userNameController.text,
passwordController.text);
prov.errorText!.isNotEmpty
? giveMeDialog(
正确的解决方案是使用监听器。您可以使用字段(枚举)“状态”,它将给出加载、成功和失败等状态,并侦听状态字段中的更改并相应地显示对话框。您可以参考如何添加监听器https://stackoverflow.com/a/72168584/1582630