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

修复Flutter中API数据无法随输入城市更新UI的问题

修复Flutter中OpenWeather API城市名刷新丢失问题

你的问题核心是城市名变量未与UI状态绑定,每次Widget重建(刷新、热重载)时,局部变量会被重新初始化,导致丢失用户输入的内容。以下是具体的修复方案:

基础修复方案(使用StatefulWidget)

通过StatefulWidget管理城市名状态,确保输入的城市名在Widget重建时不会丢失,同时触发API请求获取对应城市的天气数据。

完整示例代码

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class WeatherScreen extends StatefulWidget {
  const WeatherScreen({super.key});

  @override
  State<WeatherScreen> createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  // 用状态变量存储城市名,初始值设为默认城市
  String _cityName = 'London';
  Map<String, dynamic>? _weatherData;
  bool _isLoading = false;
  final TextEditingController _cityController = TextEditingController();

  // 调用OpenWeather API获取天气数据
  Future<void> _fetchWeather() async {
    setState(() {
      _isLoading = true;
    });

    // 替换为你的OpenWeather API Key
    const apiKey = 'YOUR_API_KEY';
    final url = Uri.parse(
        'https://api.openweathermap.org/data/2.5/weather?q=$_cityName&appid=$apiKey&units=metric');

    try {
      final response = await http.get(url);
      if (response.statusCode == 200) {
        setState(() {
          _weatherData = json.decode(response.body);
        });
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('获取天气失败:${response.statusCode}')),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('网络错误:$e')),
      );
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    // 初始化时加载默认城市天气
    _fetchWeather();
    // 绑定输入框初始值
    _cityController.text = _cityName;
  }

  @override
  void dispose() {
    // 释放控制器资源
    _cityController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('天气查询')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // 城市输入框,提交时更新城市名并请求数据
            TextField(
              controller: _cityController,
              decoration: const InputDecoration(
                labelText: '输入城市名',
                border: OutlineInputBorder(),
                suffixIcon: Icon(Icons.search),
              ),
              onSubmitted: (value) {
                setState(() {
                  _cityName = value;
                });
                _fetchWeather();
              },
            ),
            const SizedBox(height: 20),
            // 加载状态或天气信息展示
            _isLoading
                ? const CircularProgressIndicator()
                : _weatherData != null
                    ? Column(
                        children: [
                          Text(
                            _weatherData!['name'],
                            style: const TextStyle(
                                fontSize: 24, fontWeight: FontWeight.bold),
                          ),
                          const SizedBox(height: 10),
                          Text(
                            '${_weatherData!['main']['temp']}°C',
                            style: const TextStyle(fontSize: 48),
                          ),
                          Text(
                            _weatherData!['weather'][0]['description'],
                            style: const TextStyle(fontSize: 18),
                          ),
                        ],
                      )
                    : const Text('暂无数据'),
          ],
        ),
      ),
    );
  }
}

关键修复点

  • 状态变量存储城市名:将_cityName定义为State类的成员变量,而非局部变量,确保Widget重建时状态被保留。
  • TextEditingController绑定输入框:输入框内容与状态同步,即使Widget重建,输入框也能显示当前城市名。
  • 提交输入触发更新:用户提交城市名时,先更新_cityName状态,再调用API获取对应城市的天气数据。
  • 初始化与资源释放:initState中加载默认城市天气并绑定输入框初始值,dispose中释放控制器资源避免内存泄漏。

进阶方案(跨页面共享状态)

如果需要在多个页面共享城市名状态,可以使用状态管理库(如Riverpod、Provider或Bloc),将城市名状态提升到全局或父级组件中,避免每次页面重建丢失数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:47:42