You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter pop返回后获取城市天气数据但UI未更新问题

问题根源

你的UI不更新核心是两个代码逻辑错误,附带一个边界崩溃隐患:

  • 最主要问题:setState 方法的回调不支持async异步操作。你把网络请求写在setState内部,Flutter执行到setState时不会等待await的网络请求返回,会直接触发UI重建,等网络数据真正拿到的时候,本次刷新流程已经结束,自然不会把新数据渲染到界面上。
  • 第二个问题:updateUI方法的空判断逻辑不完整。当weatherData为null时,你只给三个变量赋了默认值,没有中断执行,后续代码会直接尝试从null上取下标属性,直接抛运行时异常,中断更新流程。
  • 边界隐患:城市选择页的cityName用late修饰,如果用户进入页面后没有输入内容直接返回,会触发late变量未初始化的崩溃。
修复方案

1. 修正按钮点击逻辑,把异步请求移到setState外部

先等待网络请求拿到完整数据,再调用setState更新状态:

FlatButton(
  onPressed: () async {
    dynamic typedname = await Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => Cityscreen()));
    // 用户直接返回未输入城市时终止流程
    if (typedname == null || typedname.isEmpty) return;
    // 先等网络请求返回数据
    dynamic weatherData = await weatherModel.getCityLocation(typedname);
    // 数据就绪后再触发UI更新
    setState(() {
      updateUI(weatherData);
    });
  },
)

2. 补全updateUI的空判断逻辑

空数据场景下赋值完默认值直接return,避免后续执行空对象取值操作:

void updateUI(var weatherData) {
   if (weatherData == null) {
     city = '';
     temperature = 0;
     weatherMessage = 'Unable to fetch data';
     weatherIcon = null;
     description = '';
     // 终止后续执行
     return;
   }
   id = weatherData['weather'][0]['id'];
   weatherIcon = weatherModel.getWeatherIcon(id);
   city = weatherData['name'];
   double temp = weatherData['main']['temp'];
   temperature = temp.toInt();
   weatherMessage = weatherModel.getMessage(temperature);
   description = weatherData['weather'][0]['description'];
 }

3. 修复城市选择页的变量初始化问题

给cityName设置空字符串默认值,去掉late修饰,避免未初始化崩溃:

class _CityscreenState extends State<Cityscreen> {
  // 给默认初始值,不需要late修饰
  String cityName = '';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('images/back1.jpg'),
            fit: BoxFit.fill,
          ),
        ),
        constraints: BoxConstraints.expand(),
        child: SafeArea(
          child: Column(
            children: [
              Align(
                alignment: Alignment.topLeft,
                child: FlatButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Icon(
                    Icons.arrow_back_ios,
                    size: 50.0,
                  ),
                ),
              ),
              Container(
                padding: EdgeInsets.all(20.0),
                child: TextField(
                  style: TextStyle(
                    color: Colors.black,
                  ),
                  decoration: kTextFieldDecoration,
                  onChanged: (value) {
                    cityName=value;
                  },
                ),
              ),
              FlatButton(
                  onPressed: (){
                    Navigator.pop(context,cityName);
                  },
                child: Text(
                  'Get weather',
                  style: TextStyle(
                    fontSize: 30,
                  ),
                ),
                color: Colors.deepPurpleAccent,
              ),
            ],
          ),
        ),
      ),
      // 补全原有剩余代码即可
    );
  }
}

改完之后网络请求返回的数据就可以正常触发UI刷新了。

内容的提问来源于stack exchange,提问作者Hamza Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:06:25