Flutter中Weather API数据无法导入Model问题求助
问题排查与正确实现示例
常见问题原因
- 网络请求未正确处理(状态码、JSON解析错误)
- Model类
fromJson方法与API返回结构不匹配 - FutureBuilder使用不当(每次build重新发起请求、未处理全状态)
正确实现代码
1. Model类(匹配API返回结构)
假设API返回JSON结构如下:
{ "name": "London", "main": {"temp": 15.0, "humidity": 70}, "weather": [{"description": "cloudy"}] }
对应Model类:
class WeatherModel { final String cityName; final double temp; final int humidity; final String description; WeatherModel({ required this.cityName, required this.temp, required this.humidity, required this.description, }); factory WeatherModel.fromJson(Map<String, dynamic> json) { return WeatherModel( cityName: json['name'] ?? '未知城市', temp: (json['main']['temp'] as num).toDouble(), humidity: json['main']['humidity'] as int, description: json['weather'][0]['description'] ?? '未知天气', ); } }
2. 数据获取类(含错误处理)
import 'dart:convert'; import 'package:http/http.dart' as http; class WeatherData { final String apiUrl; WeatherData(this.apiUrl); Future<WeatherModel> getData() async { try { final response = await http.get(Uri.parse(apiUrl)); if (response.statusCode == 200) { final jsonData = json.decode(response.body); return WeatherModel.fromJson(jsonData); } else { throw Exception('请求失败:状态码${response.statusCode}'); } } catch (e) { throw Exception('网络错误:$e'); } } }
3. FutureBuilder正确使用(StatefulWidget存储Future)
import 'package:flutter/material.dart'; class WeatherPage extends StatefulWidget { const WeatherPage({super.key}); @override State<WeatherPage> createState() => _WeatherPageState(); } class _WeatherPageState extends State<WeatherPage> { late Future<WeatherModel> _weatherFuture; @override void initState() { super.initState(); // 替换为你的API地址(需带密钥等参数) final weatherApi = WeatherData('https://api.openweathermap.org/data/2.5/weather?q=London&appid=你的API_KEY&units=metric'); _weatherFuture = weatherApi.getData(); // 仅初始化一次,避免重复请求 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('天气信息')), body: FutureBuilder<WeatherModel>( future: _weatherFuture, builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 错误状态 else if (snapshot.hasError) { return Center(child: Text('加载失败:${snapshot.error}')); } // 有数据状态 else if (snapshot.hasData) { final weather = snapshot.data!; return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('城市:${weather.cityName}', style: const TextStyle(fontSize: 24)), const SizedBox(height: 16), Text('温度:${weather.temp}°C', style: const TextStyle(fontSize: 20)), Text('湿度:${weather.humidity}%', style: const TextStyle(fontSize: 20)), Text('天气:${weather.description}', style: const TextStyle(fontSize: 20)), ], ), ); } // 默认空状态 else { return const Center(child: Text('无数据')); } }, ), ); } }
关键注意事项
- 不要在
FutureBuilder的future参数中直接写weatherData().getData(),这会导致每次Widget重建都重新发起请求,需在initState中初始化并存储Future变量。 - 必须处理
FutureBuilder的所有状态:加载中、错误、有数据,避免界面空白。 - Model类
fromJson方法要严格匹配API返回的JSON结构,注意嵌套字段和类型转换,可添加空值判断避免崩溃。 - 在数据获取方法中添加异常捕获,确保错误能被FutureBuilder捕获并提示。
内容的提问来源于stack exchange,提问作者Othman_Sami
相关产品推荐
相关产品推荐

