Flutter天气应用出现setState() or markNeedsBuild() called during build报错求助
问题原因
- 核心报错触发点:
LoadingScreen的页面跳转逻辑在页面未完成构建时就执行,调用Navigator会触发Overlay重绘,和当前的页面构建流程冲突,导致setState() or markNeedsBuild() called during build错误。 - 逻辑错误1:未等待
getLocationWeather()的异步返回结果就跳转,传给LocationScreen的是Future对象而非真实天气数据,会导致后续JSON解析报错。 - 逻辑错误2:
LocationScreen的updateUi方法更新业务变量后未调用setState,界面不会同步刷新最新数据。 - 细节错误:
Weather.dart中填写的API密钥和你定义的APIkey不一致,会导致接口请求401失败。
解决方案
1. 修改LoadingScreen.dart逻辑
等待页面构建完成、接口返回真实数据后再执行跳转,修正后代码如下:
class _LoadingScreenState extends State<LoadingScreen> { @override void initState(){ super.initState(); // 等待当前页面构建完成后再执行业务逻辑 WidgetsBinding.instance.addPostFrameCallback((_) async { await getLocationData(); }); } Future<void> getLocationData() async { WeatherModel weatherModel = WeatherModel(); // 加await等待接口返回真实天气数据 var weatherData = await weatherModel.getLocationWeather(); Navigator.push(context,MaterialPageRoute(builder:(context){ return LocationScreen( locationWeather: weatherData, ); })); } @override Widget build(BuildContext context) { return Scaffold( body:Center( child:SpinKitDoubleBounce( color:Colors.white, size:100, ) ) ); } }
2. 修改LocationScreen.dart的updateUi方法
增加setState触发界面刷新,同时增加空判断避免接口请求失败崩溃:
void updateUi(dynamic weatherData) { setState(() { if(weatherData == null){ temperature = 0; weatherIcon = '❌'; cityName = '获取失败'; return; } var condition = weatherData['weather'][0]['id']; temp = weatherData['main']['temp']; temperature=temp.toInt(); cityName = weatherData['name']; weatherIcon =weather.getWeatherIcon(condition); }); print(temperature); }
3. 修正API密钥
把Weather.dart中请求地址里的appid值替换为你定义的正确API密钥9f2e463e61258ef5a8b9a9bd11733b62c即可。
内容的提问来源于stack exchange,提问作者Karthik KK
相关产品推荐
相关产品推荐

