Flutter中如何将API响应的成功/错误消息展示为SnackBar或弹窗
解决方案
方案1:直接调整现有逻辑快速实现
直接修改api_manager.dart中validateOtp方法的错误分支,翻译提示文案同时增加上下文合法性判断,避免页面销毁时弹窗报错:
else if (status == 0) { final apiMsg = validateOtpData.msg; // 英文提示翻译为中文,兜底异常提示 String showMsg = apiMsg == "OTP is either expired or not valid." ? "OTP已过期或无效" : apiMsg ?? "验证失败,请稍后重试"; final snackBar = SnackBar(content: Text(showMsg), backgroundColor: Colors.grey); // 仅页面存活时弹出提示 if(context.mounted) { ScaffoldMessenger.of(context).showSnackBar(snackBar); } }
方案2:将响应结果返回给OTP页面自行处理(更灵活,可自由选择SnackBar/AlertDialog)
第一步:修改validateOtp方法返回结构
调整api_manager.dart的validateOtp方法,将验证状态和提示信息返回给调用页,同时增加异常捕获:
Future<Map<String, dynamic>> validateOtp(BuildContext context, String otp, LogedinUser? userData, UserPlan? userPlan) async { final String otpUrl = "$baseUrl/otp/validate"; try { var formData = FormData.fromMap({ 'user_id': userData!.userId, 'otp': otp, 'device_id': userData.deviceId, }); var response = await dio.post(otpUrl, data: formData); final validateOtpData = validateOtpFromJson(response.data); final status = validateOtpData.success; if (response.statusCode == 200) { if (status == 1) { // 验证成功跳转首页 if(context.mounted) { Navigator.push( context, MaterialPageRoute( builder: (context) => DashBoard( user: userData, userPlan: userPlan, ), ), ); } return {"success": true, "msg": "验证成功"}; } else { // 验证失败返回翻译后的错误信息 String errorMsg = validateOtpData.msg == "OTP is either expired or not valid." ? "OTP已过期或无效" : validateOtpData.msg ?? "验证失败"; return {"success": false, "msg": errorMsg}; } } else { return {"success": false, "msg": "网络请求失败"}; } } catch(e) { return {"success": false, "msg": "请求异常,请稍后重试"}; } }
第二步:修改OTP页面点击逻辑,拿到结果后自行弹窗
ElevatedButton( onPressed: () async { // 前置校验:OTP未输全时提前拦截 if(otp.length != 6) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("请输入完整的6位OTP码"))); return; } var result = await ApiManager().validateOtp(context, otp, userData, userPlan); if(context.mounted && !result["success"]) { // 方案A:弹出SnackBar,二选一即可 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(result["msg"]), backgroundColor: Colors.grey) ); // 方案B:弹出AlertDialog,不需要则注释即可 // showDialog( // context: context, // builder: (context) => AlertDialog( // title: const Text("验证失败"), // content: Text(result["msg"]), // actions: [ // TextButton(onPressed: () => Navigator.pop(context), child: const Text("确定")) // ], // ) // ); } }, child: const Text("Verify"), )
优化建议
你当前代码中initState里的validateOtp调用可以删除,刚进入页面用户还未输入OTP,该调用无实际意义。
内容的提问来源于stack exchange,提问作者Dhaval Chaudhari
相关产品推荐
相关产品推荐

