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

Flutter按钮点击后调用OpenWeatherMap REST API的实现问题

在Flutter中实现按钮触发OpenWeatherMap API请求

嘿,恭喜你已经搞定了API调用的核心代码!接下来咱们把按钮点击和这个请求逻辑绑定起来,让用户一点按钮就能拿到天气数据。我给你一步步拆解具体实现:

1. 先完善你的API类(补全代码)

你已经写了基础的OpenWeatherApi类,我帮你补全URL部分,确保能正确发起请求:

class OpenWeatherApi {
  static const _API_KEY = "asdbaklsadfkasdlfkasdjfl"; // 记得替换成你的真实API Key

  Future<CurrentWeather> getCurrentWeather(String location) async {
    final url = Uri.parse(
      "https://api.openweathermap.org/data/2.5/weather?q=$location&appid=$_API_KEY&units=metric"
    );
    final response = await http.get(url);

    if (response.statusCode == 200) {
      return CurrentWeather.fromJson(jsonDecode(response.body));
    } else {
      throw Exception("Failed to load weather data");
    }
  }
}

// 记得定义CurrentWeather模型类来解析返回的JSON
class CurrentWeather {
  final String cityName;
  final double temperature;

  CurrentWeather({required this.cityName, required this.temperature});

  factory CurrentWeather.fromJson(Map<String, dynamic> json) {
    return CurrentWeather(
      cityName: json['name'],
      temperature: json['main']['temp'].toDouble(),
    );
  }
}

2. 构建带按钮的页面(使用StatefulWidget)

因为要处理异步请求的状态(加载中、成功、失败),咱们用StatefulWidget来管理页面状态:

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

  @override
  State<WeatherPage> createState() => _WeatherPageState();
}

class _WeatherPageState extends State<WeatherPage> {
  final _api = OpenWeatherApi();
  final _locationController = TextEditingController(text: "London"); // 默认城市
  bool _isLoading = false;
  CurrentWeather? _weatherData;
  String? _errorMessage;

  // 点击按钮触发的请求方法
  void _fetchWeather() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final weather = await _api.getCurrentWeather(_locationController.text);
      setState(() {
        _weatherData = weather;
      });
    } catch (e) {
      setState(() {
        _errorMessage = e.toString();
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @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: _locationController,
              decoration: const InputDecoration(
                labelText: "输入城市名称",
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _isLoading ? null : _fetchWeather,
              child: _isLoading 
                  ? const CircularProgressIndicator(color: Colors.white) 
                  : const Text("查询天气"),
            ),
            const SizedBox(height: 24),
            // 展示结果或错误信息
            if (_isLoading)
              const Text("加载中...")
            else if (_errorMessage != null)
              Text("出错了: $_errorMessage", style: const TextStyle(color: Colors.red))
            else if (_weatherData != null)
              Column(
                children: [
                  Text("城市: ${_weatherData!.cityName}", style: const TextStyle(fontSize: 18)),
                  const SizedBox(height: 8),
                  Text("温度: ${_weatherData!.temperature}°C", style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
                ],
              ),
          ],
        ),
      ),
    );
  }
}

3. 注意事项

  • 别忘了在pubspec.yaml里添加依赖:http: ^1.1.0(或者最新版本),然后执行flutter pub get
  • 重要提示:不要把API Key硬编码在代码里!如果是正式项目,建议用环境变量或者配置文件来管理,避免泄露
  • 可以根据需求扩展CurrentWeather模型,添加更多天气信息(比如湿度、风速等)

这样一来,用户点击按钮后就会触发API请求,页面也会根据请求状态展示不同的内容啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:40