目录

  1. 概述
  2. 引入三方库步骤
  3. 天气详情页面实战案例
  4. 常见错误及解决方案
  5. 总结

概述

本章节主要详细介绍在使用跨平台框架Flutter开发鸿蒙应用程序,使用Flutter三方库 http 库进行网络请求,实现天气详情功能。http是纯dart语言编写,无需进行鸿蒙化适配,可以直接使用的。

🎯 本教程目标

通过本教程,你将学会:

  1. ✅ 如何在 Flutter 项目中引入 http 相关依赖
  2. ✅ 如何配置 HTTP 请求(URL、请求头、查询参数)
  3. ✅ 如何解析 JSON 响应数据
  4. 如何在天气详情页面中使用 http 实现天气数据请求和展示
  5. ✅ 最终在鸿蒙设备上运行效果如下图所示

📁 项目文件结构

在开始之前,让我们先了解一下项目结构:

lib/
├── models/                       # 数据模型目录
│   ├── weather_models.dart      # 📊 天气数据模型定义
│   └── weather_models.g.dart    # ⚙️ 自动生成的 JSON 序列化代码
└── screens/                      # 页面文件目录
    └── weather_detail_page.dart # 🌤️ 天气详情页面(使用 HTTP 进行网络请求)

🎯 本教程将修改的文件

严格按照以下顺序修改文件,每个步骤完成后立即验证:

  1. lib/screens/weather_detail_page.dart - 🌤️ 天气详情页面,使用 HTTP 进行网络请求

🛠️ 技术栈

  • http: Flutter 官方推荐的 HTTP 客户端库
  • json_annotation: JSON 序列化注解支持(用于数据模型)
  • json_serializable: JSON 序列化代码生成器(用于数据模型)

🌤️ 和风天气 API 简介

和风天气提供全球天气预报服务,本教程使用:

  • 🌡️ 实时天气查询 - /v7/weather/now
  • 📅 每日天气预报 - /v7/weather/{days}(支持 3d、7d、10d、15d、30d)

API 文档地址:

  • 实时天气:https://dev.qweather.com/docs/api/weather/weather-now/
  • 每日预报:https://dev.qweather.com/docs/api/weather/weather-daily-forecast/

引入三方库步骤

📋 流程图概览

📝 开始引入三方库

📄 步骤1.1: 打开 pubspec.yaml 文件

📝 步骤1.2: 添加 http 依赖到 dependencies 部分

💾 步骤1.3: 保存文件

⬇️ 步骤2: 运行 flutter pub get

✅ 安装成功?

🔍 步骤3: 验证安装

❌ 检查版本兼容性

🎉 完成引入

📝 步骤 1:添加依赖到 pubspec.yaml

步骤 1.1:打开 pubspec.yaml 文件

文件路径: pubspec.yaml(项目根目录)

操作说明:

  1. 📂 在 IDE 中打开项目根目录
  2. 📄 找到并打开 pubspec.yaml 文件
  3. 👀 确认文件内容,找到 dependencies: 部分
步骤 1.2:添加运行时依赖

位置: pubspec.yaml 文件的 dependencies: 部分

操作步骤:

  1. 📍 找到 dependencies: 部分
  2. 📝 在 dependencies: 下添加以下内容:
dependencies:
  flutter:
    sdk: flutter
  
  # HTTP 网络请求库
  http: ^1.1.0

验证:

  • ✅ 确认缩进正确(使用2个空格)
  • ✅ 确认版本号正确
  • ✅ 确认没有语法错误(冒号、引号等)

版本说明:

  • http: ^1.1.0 - HTTP 客户端库,Flutter 官方推荐

重要提示:

  • ⚠️ 如果版本冲突,可以运行 flutter pub upgrade 升级所有依赖
步骤 1.3:保存文件

操作说明:

  1. 💾 保存 pubspec.yaml 文件(Ctrl+S 或 Cmd+S)
  2. ✅ 确认文件已保存

⬇️ 步骤 2:安装依赖

操作步骤:

  1. 📂 打开终端(Terminal),切换到项目根目录

    cd /path/to/your/project
    
  2. ⌨️ 执行以下命令:

    flutter pub get
    
  3. ⏳ 等待安装完成(可能需要10-30秒)

命令说明:

  • flutter pub get - 下载并安装所有在 pubspec.yaml 中声明的依赖包
  • 安装成功后,依赖包会被下载到项目的 .dart_tool 目录

预期输出:

Running "flutter pub get" in ffohnotes...
Resolving dependencies...
Got dependencies!

验证:

  • ✅ 确认终端显示 “Got dependencies!”
  • ✅ 确认没有错误信息

✅ 步骤 3:验证安装

操作步骤:

  1. 📄 检查 pubspec.lock 文件,确认 http 已安装

  2. 🔍 在代码中尝试导入 http:

    import 'package:http/http.dart' as http;
    
  3. ✅ 确认 IDE 没有报错(红色波浪线)

验证:

  • ✅ 确认 pubspec.lock 中包含 http: 1.1.0
  • ✅ 确认导入语句没有错误

天气详情页面实战案例

📄 文件说明:lib/screens/weather_detail_page.dart

文件作用: 天气详情页面 UI 实现,使用 HTTP 进行所有网络请求

HTTP 使用位置:

  1. 获取实时天气_getCurrentWeather() 中使用 http.get() 获取实时天气
  2. 获取每日预报_getDailyForecast() 中使用 http.get() 获取天气预报
  3. 加载数据_loadWeatherData() 中并发调用上述两个方法

📋 天气详情页面功能实现流程图

🚀 页面启动

📥 initState: 加载天气数据

🌐 并发请求两个 API

实时天气 API

每日预报 API

解析 JSON 响应

解析 JSON 响应

📊 转换为模型对象

请求成功?

✅ 更新UI状态

❌ 显示错误信息

🎨 渲染UI组件

🌡️ 当前天气卡片

📅 预报天数选择器

📋 天气预报列表

👆 用户切换预报天数

更新选中天数

👆 用户下拉刷新

🎯 天气详情页面实现的功能模块

1. 🔧 配置 API 常量和导入

功能说明: 配置 API 密钥、基础地址和导入必要的库

代码位置: lib/screens/weather_detail_page.dart

操作步骤:

  1. 📝 修改导入语句:
// 导入 Flutter Material 设计库
import 'package:flutter/material.dart';
// 导入 http HTTP 客户端
import 'package:http/http.dart' as http;
// 导入数据模型
import '../models/weather_models.dart';
// 导入 JSON 序列化
import 'dart:convert';
  1. 📝 在 _WeatherDetailPageState 类中添加 API 配置常量:
class _WeatherDetailPageState extends State<WeatherDetailPage> {
  // API 密钥(实际使用时应该从配置文件或环境变量读取)
  static const String _apiKey = '和风天气控制台获取API KEY';
  
  // API 基础地址
  static const String _baseUrl = '和风天气控制台获取API HOST';
  
  // 当前城市(默认北京)
  final String _currentCity = '北京';
  final String _currentLocationId = '101010100';
  
  // ... 其他状态变量
}

验证:

  • ✅ 确认导入了 http
  • ✅ 确认导入了 dart:convert 用于 JSON 解析
  • ✅ 确认 API 配置常量已添加
2. 🌡️ 获取实时天气 (_getCurrentWeather)

功能说明: 使用 HTTP 库调用和风天气 API 获取实时天气数据

使用 HTTP: http.get() 方法发送 GET 请求

操作步骤:

  1. 📝 添加 _getCurrentWeather() 方法:
  /// 获取实时天气
  /// 
  /// **功能说明:** 使用 http 库调用和风天气 API 获取实时天气
  /// **API 文档:** https://dev.qweather.com/docs/api/weather/weather-now/
  Future<WeatherResponse> _getCurrentWeather() async {
    try {
      // 构建请求 URL
      final uri = Uri.parse('$_baseUrl/v7/weather/now').replace(
        queryParameters: {
          'location': _currentLocationId,
          'lang': 'zh',
        },
      );
      
      // 发送 GET 请求
      final response = await http.get(
        uri,
        headers: {
          'X-QW-Api-Key': _apiKey,
        },
      );
      
      // 检查响应状态码
      if (response.statusCode == 200) {
        // 解析 JSON 响应
        final data = jsonDecode(response.body) as Map<String, dynamic>;
        
        // 检查 API 返回的状态码
        if (data['code'] == '200') {
          return WeatherResponse.fromJson(data);
        } else {
          throw Exception('获取天气失败: ${data['code']}');
        }
      } else {
        throw Exception('HTTP ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('获取实时天气失败: $e');
    }
  }

关键点说明:

  1. 构建请求 URL

    • Uri.parse() - 解析基础 URL
    • .replace(queryParameters: {...}) - 添加查询参数(URL 参数)
  2. 发送 GET 请求

    • http.get(uri, headers: {...}) - 发送 GET 请求
    • headers - 请求头,包含 API Key
  3. 响应处理

    • response.statusCode - HTTP 状态码(200 表示成功)
    • response.body - 响应体(字符串格式的 JSON)
    • jsonDecode() - 将 JSON 字符串解析为 Map
  4. 数据转换

    • WeatherResponse.fromJson(data) - 将 Map 转换为模型对象

验证:

  • ✅ 确认使用了 http.get() 方法
  • ✅ 确认 URL 和查询参数正确
  • ✅ 确认请求头包含 API Key
  • ✅ 确认响应数据正确解析

image-20260126110228907

3. 📅 获取每日预报 (_getDailyForecast)

功能说明: 使用 HTTP 库调用和风天气 API 获取每日天气预报

使用 HTTP: http.get() 方法发送 GET 请求

操作步骤:

  1. 📝 添加 _getDailyForecast() 方法:
  /// 获取每日天气预报
  /// 
  /// **功能说明:** 使用 http 库调用和风天气 API 获取每日天气预报
  /// **API 文档:** https://dev.qweather.com/docs/api/weather/weather-daily-forecast/
  Future<DailyForecastResponse> _getDailyForecast() async {
    try {
      // 构建请求 URL(使用动态预报天数)
      final uri = Uri.parse('$_baseUrl/v7/weather/$_selectedDays').replace(
        queryParameters: {
          'location': _currentLocationId,
          'lang': 'zh',
        },
      );
      
      // 发送 GET 请求
      final response = await http.get(
        uri,
        headers: {
          'X-QW-Api-Key': _apiKey,
        },
      );
      
      // 检查响应状态码
      if (response.statusCode == 200) {
        // 解析 JSON 响应
        final data = jsonDecode(response.body) as Map<String, dynamic>;
        
        // 检查 API 返回的状态码
        if (data['code'] == '200') {
          return DailyForecastResponse.fromJson(data);
        } else {
          throw Exception('获取预报失败: ${data['code']}');
        }
      } else {
        throw Exception('HTTP ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('获取${_selectedDays}预报失败: $e');
    }
  }

关键点说明:

  1. 动态 URL 路径

    • $_baseUrl/v7/weather/$_selectedDays - 使用字符串插值动态构建路径
    • _selectedDays 可以是 ‘3d’、‘7d’、‘10d’、‘15d’、‘30d’
  2. 并发请求

    • _loadWeatherData() 中使用 Future.wait() 并发请求两个 API
    • 提高加载速度,减少等待时间

验证:

  • ✅ 确认使用了动态路径参数
  • ✅ 确认查询参数正确传递
  • ✅ 确认响应数据正确解析

image-20260126110256305

4. 🔄 加载天气数据 (_loadWeatherData)

功能说明: 并发请求实时天气和预报数据,更新 UI

操作步骤:

  1. 📝 修改 _loadWeatherData() 方法:
  /// 加载天气数据
  /// 
  /// **功能说明:** 使用 http 库调用和风天气 API 获取实时天气和预报数据
  Future<void> _loadWeatherData() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      // 并发请求实时天气和预报数据
      final results = await Future.wait([
        _getCurrentWeather(),
        _getDailyForecast(),
      ]);

      setState(() {
        _currentWeather = results[0] as WeatherResponse;
        _forecast = results[1] as DailyForecastResponse;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = '加载失败: $e';
        _isLoading = false;
      });
    }
  }

关键点说明:

  1. 并发请求

    • Future.wait([...]) - 等待多个 Future 完成
    • 两个 API 请求同时进行,提高效率
  2. 状态管理

    • setState() - 更新 UI 状态
    • 加载状态、错误状态、数据状态

验证:

  • ✅ 确认使用了 Future.wait() 并发请求
  • ✅ 确认状态更新正确
  • ✅ 确认错误处理已添加

image-20260126110404338

🎨 UI 设计要点

  • 🎨 现代简约风格:使用浅灰色背景(Colors.grey.shade50)、白色卡片、圆角设计(20px)
  • 📦 卡片设计:使用白色背景、阴影效果,提升视觉层次
  • 📱 响应式布局:适配不同屏幕尺寸,使用 SingleChildScrollView
  • ⏳ 加载状态:显示紫色加载指示器(Color(0xFF6366F1))和友好的加载提示
  • ❌ 错误处理:友好的错误提示和重试按钮
  • 🎯 交互反馈:预报天数选择器、可展开的预报项、下拉刷新

常见错误及解决方案

🔧 错误处理流程图

连接超时

网络错误

400错误

401错误

404错误

解析错误

⚠️ 遇到错误

错误类型?

⏱️ 检查网络连接

🌐 检查网络设置

✅ 检查请求参数

🔑 检查API密钥

🔍 检查API路径

📋 检查响应格式

✅ 问题解决

错误 1:连接超时

错误信息:

TimeoutException: Connection timeout

原因分析:

  • 网络连接慢或服务器响应慢
  • 默认超时时间过短

解决方案:

  Future<WeatherResponse> _getCurrentWeather() async {
    try {
      final uri = Uri.parse('$_baseUrl/v7/weather/now').replace(
        queryParameters: {
          'location': _currentLocationId,
          'lang': 'zh',
        },
      );
      
      // 设置超时时间(30秒)
      final response = await http.get(
        uri,
        headers: {
          'X-QW-Api-Key': _apiKey,
        },
      ).timeout(
        const Duration(seconds: 30),
        onTimeout: () {
          throw Exception('请求超时,请检查网络连接');
        },
      );
      
      // ... 处理响应
    } catch (e) {
      throw Exception('获取实时天气失败: $e');
    }
  }

错误 2:网络错误

错误信息:

SocketException: Failed host lookup

原因分析:

  • 设备未连接网络
  • DNS 解析失败
  • baseUrl 地址错误

解决方案:

  1. 检查网络连接

  2. 确认 baseUrl 正确:

    static const String _baseUrl = '和风天气控制台查看API HOST';
    
  3. 检查 API 密钥是否正确

错误 3:400 Bad Request

错误信息:

Exception: HTTP 400

原因分析:

  • 请求参数格式错误
  • 缺少必需参数

解决方案:

  1. 检查查询参数:

    queryParameters: {
      'location': _currentLocationId,  // 确保 locationId 正确
      'lang': 'zh',                    // 确保语言参数正确
    },
    
  2. 检查 URL 格式:

    // 正确:使用 Uri.parse() 和 replace()
    final uri = Uri.parse('$_baseUrl/v7/weather/now').replace(
      queryParameters: {...},
    );
    

错误 4:401 Unauthorized

错误信息:

Exception: HTTP 401

原因分析:

  • API Key 无效或未设置
  • API Key 已过期

解决方案:

  1. 检查 API Key 是否正确:

    static const String _apiKey = '你的API密钥';
    
  2. 确认请求头已添加:

    headers: {
      'X-QW-Api-Key': _apiKey,
    },
    
  3. 在和风天气控制台检查 API Key 状态

错误 5:404 Not Found

错误信息:

Exception: HTTP 404

原因分析:

  • API 路径错误
  • baseUrl 配置错误

解决方案:

  1. 确认 API 路径正确:

    // 实时天气
    Uri.parse('$_baseUrl/v7/weather/now')
    
    // 每日预报(注意路径参数)
    Uri.parse('$_baseUrl/v7/weather/$_selectedDays')
    
  2. 确认 baseUrl 不包含路径:

    // 正确
    static const String _baseUrl = '和风天气控制台查看API HOST';
    
    // 错误(不要包含路径)
    static const String _baseUrl = '和风天气控制台查看API HOST/v7';
    

错误 6:JSON 解析错误

错误信息:

FormatException: Unexpected character

原因分析:

  • 响应不是有效的 JSON
  • 响应格式与预期不符

解决方案:

  1. 检查响应数据结构:

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body) as Map<String, dynamic>;
      
      // 检查响应格式
      if (data['code'] == '200') {
        return WeatherResponse.fromJson(data);
      } else {
        throw Exception('API返回错误: ${data['code']}');
      }
    }
    
  2. 打印响应内容进行调试:

    print('响应状态码: ${response.statusCode}');
    print('响应内容: ${response.body}');
    

总结

📊 完整实现流程图

🚀 项目开始

📦 步骤1: 引入三方库

📄 1.1: 添加 http 到 pubspec.yaml

⬇️ 1.2: 运行 flutter pub get

✅ 1.3: 验证安装

🌤️ 步骤2: 在天气详情页面使用 HTTP

📝 2.1: 导入 http 包和 dart:convert

⚙️ 2.2: 配置 API 常量和请求头

🌐 2.3: 实现获取实时天气方法

📅 2.4: 实现获取每日预报方法

🔄 2.5: 实现并发加载数据方法

🎨 2.6: 更新UI显示

✅ 项目完成

📋 本教程完成的内容

本教程详细介绍了如何在 Flutter 项目天气详情页面中使用 HTTP 进行网络请求,实现天气数据获取和展示功能。主要内容包括:

  1. 📦 引入三方库:添加 HTTP 依赖到 pubspec.yaml
  2. 🌤️ 天气详情页面实现:在天气详情页面中使用 HTTP 进行网络请求
    • 🔧 配置 API 常量和导入(_apiKey_baseUrl
    • 🌡️ 获取实时天气功能(_getCurrentWeather
    • 📅 获取每日预报功能(_getDailyForecast
    • 🔄 并发加载数据(_loadWeatherData
    • ✅ 错误处理和用户提示
  3. 🔧 错误处理:提供常见错误及解决方案,帮助新手快速解决问题

💡 关键要点

  • ⚙️ HTTP 配置:使用 Uri.parse() 构建 URL,使用 replace() 添加查询参数
  • 📝 请求头:在 headers 参数中添加 API Key(X-QW-Api-Key
  • 🌐 GET 请求:使用 http.get() 发送 GET 请求
  • 📊 响应处理:检查状态码,使用 jsonDecode() 解析 JSON,转换为模型对象
  • 🔄 并发请求:使用 Future.wait() 并发请求多个 API,提高效率
  • 🛡️ 错误处理:捕获异常,提供友好的错误提示
  • 🌤️ 天气详情页面使用 HTTP:天气详情页面的所有网络请求都通过 HTTP 完成

📚 参考资源


🎉 恭喜! 你已经完成了 HTTP 客户端天气详情页面的集成教程。现在你可以在 Flutter 项目中轻松使用 HTTP 进行网络请求了!

💬 遇到问题? 查看 常见错误及解决方案 章节,或参考官方文档。

⚠️ 重要提示: 本教程中的 API 密钥需要替换为你的真实密钥。在生产环境中,请使用安全的方式存储和管理 API 密钥。

🎉 祝你开发顺利! 🚀
欢迎加入开源鸿蒙跨平台社区

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐