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

Flutter中点击TextFormField图标后变量未同步更新问题求助

问题分析与解决方案:Flutter更新城市后API调用未同步

问题原因

你代码里的futureWeather仅在initState阶段执行了一次API请求,用的是初始城市Lahore。后续点击搜索图标更新city变量时,只是修改了变量值,但没有重新发起新的API请求,FutureBuilder一直绑定的是第一次的请求结果,所以接口始终用初始值。

解决方案

在点击搜索图标时,不仅更新city变量,还要重新调用ApiService.getWeather并更新futureWeather,让FutureBuilder能获取新的请求结果。同时可以增加输入为空的判断,避免无效请求。

修改后的完整代码:

import 'package:flutter/material.dart';
import 'model/Weather.dart';
import 'ApiService.dart';

class WeatherData extends StatefulWidget {
  WeatherData({Key? key}) : super(key: key);

  @override
  State<WeatherData> createState() => _WeatherDataState();
}

class _WeatherDataState extends State<WeatherData> {
  late Future<WeatherModel> futureWeather;
  TextEditingController controller = TextEditingController();
  String city = "Lahore";

  @override
  void initState() {
    super.initState();
    futureWeather = ApiService().getWeather(location: city);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder<WeatherModel>(
          future: futureWeather,
          builder: (context, snapshot) {
            if (snapshot.data != null) {
              return Scaffold(
                appBar: AppBar(
                  backgroundColor: Colors.transparent,
                  elevation: 0,
                  title: Text('Weather App', style: TextStyle(color: Colors.black)),
                  centerTitle: true,
                  leading: Icon(Icons.menu, color: Colors.black),
                ),
                body: SingleChildScrollView(
                  child: Center(
                    child: Padding(
                      padding: const EdgeInsets.all(30.0),
                      child: Column(
                        children: [
                          SizedBox(height: 20),
                          Icon(Icons.wb_sunny_rounded, color: Colors.amber, size: 70),
                          SizedBox(height: 10),
                          Text(
                            "${(snapshot.data!.main.temp - 273.15).toStringAsFixed(2)}",
                            style: TextStyle(fontSize: 30),
                          ),
                          SizedBox(height: 5),
                          Text(snapshot.data!.name, style: TextStyle(fontSize: 15, color: Colors.black38)),
                          SizedBox(height: 20),
                          TextFormField(
                            controller: controller,
                            decoration: InputDecoration(
                              hintText: 'Input City',
                              labelStyle: TextStyle(
                                color: Color(0xFF6200EE),
                              ),
                              suffixIcon: IconButton(
                                onPressed: () {
                                  setState(() {
                                    if (controller.text.isNotEmpty) {
                                      city = controller.text;
                                      // 重新发起API请求并更新futureWeather
                                      futureWeather = ApiService().getWeather(location: city);
                                      controller.clear();
                                    }
                                  });
                                },
                                icon: Icon(Icons.search),
                              ),
                              border: OutlineInputBorder(),
                            ),
                          ),
                          SizedBox(height: 40),
                          Text("Additional Information", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87)),
                          SizedBox(height: 30),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text("Wind", style: TextStyle(fontSize: 14)),
                              Text(snapshot.data!.wind.speed.toString(), style: TextStyle(fontSize: 14)),
                              Text("Pressure", style: TextStyle(fontSize: 14)),
                              Text(snapshot.data!.main.pressure.toString(), style: TextStyle(fontSize: 14)),
                            ],
                          ),
                          SizedBox(height: 10),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text("Humidity", style: TextStyle(fontSize: 14)),
                              Text(snapshot.data!.main.humidity.toString(), style: TextStyle(fontSize: 14)),
                              Text("Feels Like", style: TextStyle(fontSize: 14)),
                              Text("${(snapshot.data!.main.feelsLike - 273.15).toStringAsFixed(2)}", style: TextStyle(fontSize: 14)),
                            ],
                          ),
                          SizedBox(height: 100),
                          CircleAvatar(
                            radius: 30,
                            backgroundColor: Colors.black12,
                            child: Icon(Icons.mic_outlined, color: Colors.black, size: 35),
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              );
            } else if (snapshot.hasError) {
              return Center(child: Text('请求失败:${snapshot.error}'));
            }
            return const Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}

关键修改点

  • 在搜索图标点击事件中,更新city后重新调用ApiService.getWeather()并赋值给futureWeather,触发FutureBuilder重建加载新数据
  • 增加输入为空判断,避免无效API请求
  • 修正额外信息区域中写死的湿度、体感温度值,改为从接口返回数据中获取

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 04:45:42