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
相关产品推荐
相关产品推荐

