Flutter使用Places API获取经纬度存入SharedPreferences异常求助
问题根源与解决方案
核心问题1:经纬度存储失败
你的代码存在3个直接导致经纬度存储失败的问题:
- 经纬度存储逻辑写在
getPlaceDetailWithLatLng异步回调中,该回调是在用户点击地址联想项后,Places API返回地点详情时才触发,比itmClick回调(用户点击立刻触发)执行晚。如果用户点完地址立刻点保存按钮,经纬度还没返回就执行了存储逻辑,自然存不上。 saveText方法中没有编写经纬度的存储代码,你将这部分逻辑注释后仅在回调里单独存储,和其他业务数据存储逻辑分离,很容易出现时序错位。- 你在回调中调用了
prefs.commit(),该方法是iOS端的废弃方法,Flutter中setString本身已经是异步持久化操作,额外调用commit属于无效操作,还可能引发兼容问题。
核心问题2:saveText无法在回调中访问
不存在上下文无法访问的问题,Dart的闭包会自动捕获State类的成员方法,你之前只是将调用代码注释了,取消注释即可正常调用,不过更推荐统一在点击保存按钮时处理所有存储逻辑,避免重复写入。
修复步骤
步骤1:新增State成员变量存储经纬度
在_UserProfileState类中新增两个变量暂存获取到的经纬度:
class _UserProfileState extends State<UserProfile> { TextEditingController textnamecontroller = TextEditingController(); TextEditingController dateinput = TextEditingController(); TextEditingController placecontroller = TextEditingController(); // 新增经纬度暂存变量 String? _latitude; String? _longitude; // 其余原有代码... }
步骤2:修改getPlaceDetailWithLatLng回调逻辑
移除回调内的SharedPreferences存储操作,仅给成员变量赋值即可:
getPlaceDetailWithLatLng: (Prediction prediction) { print("placeDetails${prediction.lng.toString()}"); print("place lat long${prediction.lat.toString()} ${prediction.lng.toString()}"); _latitude = prediction.lat.toString(); _longitude = prediction.lng.toString(); },
步骤3:修改saveText方法统一存储所有数据
补上经纬度存储逻辑,同时修复原有打印代码的参数错误:
Future<bool> saveText() async{ String name = textnamecontroller.text; String registrationDate = dateinput.text; String location = placecontroller.text; // 增加非空校验,避免无效存储 if (_latitude == null || _longitude == null) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("请选择有效的地址"))); return false; } SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('name', name); await prefs.setString('registration_date', registrationDate); await prefs.setString('location', location); // 新增经纬度存储 await prefs.setString("latitude", _latitude!); await prefs.setString("longitude", _longitude!); // 修复原有打印逻辑:getString入参是存储的key,不是变量值 print(prefs.getString('name')); print(prefs.getString('location')); print(prefs.getString('latitude')); print(prefs.getString('longitude')); return true; }
其他需修复的代码问题
initState中用到了未定义的timeinput控制器,要么删除该行代码,要么补上对应的控制器定义。- 原有代码中
print(prefs.getString(birthplace)!)的birthplace变量未定义,属于废弃逻辑可以直接删除。
内容的提问来源于stack exchange,提问作者Purna Satya
相关产品推荐
相关产品推荐

