Flutter子页面向父页面传数据时执行顺序异常问题
问题出在哪
你这是异步操作顺序搞反了,导致父页面提前拿到null,子页面的位置数据还没处理完就被返回了。
从代码和调试输出能看出来:
- 子页面的
savePlace是异步方法,但你没在这个方法里调用Navigator.pop传递数据; - 你大概率是在调用
savePlace之后直接执行了Navigator.pop(没等异步请求完成),所以父页面先收到null,之后子页面的HTTP请求才跑完打印数据。
怎么解决
1. 给子页面的savePlace加Navigator.pop
等拿到位置数据后,再调用Navigator.pop把数据传回父页面,同时处理下地址获取失败的情况:
void savePlace(double lat, double lng) async { final url = Uri.parse( 'https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lng&key=myapikey'); final response = await http.get(url); final resData = json.decode(response.body); // 加个空判断,防止接口返回空数组导致崩溃 if (resData['results'] == null || resData['results'].isEmpty) { Navigator.pop(context, null); return; } final address = resData['results'][0]["formatted_address"]; pickedLocation = PickupLocation( latitude: lat, longitude: lng, address: address, ); isGettingLocation = false; print("this first"); print(pickedLocation); // 把数据传回去并关闭页面 Navigator.pop(context, pickedLocation); }
2. 按钮点击要等savePlace完成
按钮点击时,必须等异步的savePlace执行完,不能提前跳回父页面:
// 子页面按钮的点击逻辑 onPressed: () async { // 假设你已经拿到lat和lng await savePlace(lat, lng); // 这里不用再手动pop,savePlace里已经处理了 },
3. 父页面加个空判断(可选)
避免拿到null时做无用的setState:
void locationData() async { final selectedLocation = await Navigator.of(context).push(MaterialPageRoute( builder: (ctx) => ParentScreen(), // 这里注意:你写的ParentScreen应该是子页面的类名,比如PickupLocationScreen? )); if (selectedLocation != null) { setState(() { pickedLocation = selectedLocation; }); } print("should be second"); print(pickedLocation); }
为什么这样管用
savePlace里的await http.get会等HTTP请求跑完才继续往下走,确保拿到地址数据后再生成PickupLocation;- 只有拿到有效数据后才调用
Navigator.pop,父页面的await Navigator.push会一直等到子页面pop,才能拿到正确的位置数据; - 按钮点击用
await等savePlace完成,不会提前关闭子页面。
内容的提问来源于stack exchange,提问作者Virist
相关产品推荐
相关产品推荐

