news 2026/9/21 17:49:33

Flutter+DevEco Studio实战:简易天气查询工具开发指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter+DevEco Studio实战:简易天气查询工具开发指南

跨平台开发与HarmonyOS生态融合的趋势下,利用Flutter快速构建UI、DevEco Studio适配HarmonyOS设备的开发模式,能有效提升应用开发效率。本文将以“简易天气查询工具”为案例,详细讲解Flutter与DevEco Studio结合开发的全流程,涵盖环境复用、项目搭建、网络请求、数据展示及HarmonyOS适配等核心环节,适合具备基础Flutter和HarmonyOS开发基础的开发者学习参考。

Flutter+DevEco Studio实战:简易天气查询工具开发指南大纲

项目背景与目标
  • 介绍Flutter框架的跨平台优势
  • DevEco Studio作为HarmonyOS开发工具的特点
  • 简易天气查询工具的功能需求和适用场景
开发环境配置
  • 安装Flutter SDK并配置环境变量
  • 安装DevEco Studio及HarmonyOS开发插件
  • 检查Flutter与DevEco Studio的兼容性
项目初始化
  • 使用Flutter CLI创建新项目
  • 在DevEco Studio中导入Flutter项目
  • 配置项目依赖(如http、provider等常用库)
界面设计与布局
  • 使用Flutter Widget构建主页面框架
  • 实现城市搜索输入框和查询按钮
  • 设计天气信息展示区域(温度、湿度、天气图标等)
数据获取与处理
  • 调用第三方天气API(如和风天气)
  • 解析返回的JSON数据并转换为Dart对象
  • 使用Provider或Bloc进行状态管理
功能逻辑实现
  • 实现城市搜索功能与API请求绑定
  • 处理网络请求异常和加载状态
  • 动态更新UI以反映天气数据变化
跨平台适配与优化
  • 检查HarmonyOS平台上的兼容性问题
  • 优化布局在不同设备上的显示效果
  • 测试应用在Android/iOS/HarmonyOS上的运行情况
调试与发布
  • 使用DevEco Studio的调试工具排查问题
  • 生成HarmonyOS应用发布包(.hap文件)
  • 上架到华为应用市场的简要流程说明
总结与扩展
  • 回顾关键技术点和解决方案
  • 提出进一步功能扩展建议(如多语言支持、天气预警等)
  • 推荐学习资源与社区支持

一、项目概述与环境复用

1.1 项目核心功能

本次开发的简易天气查询工具,实现3个核心功能:输入城市名称查询天气、展示实时温度/天气状况/风力等信息、处理网络异常与空输入提示。项目采用Flutter构建跨平台UI,通过第三方天气API获取数据,最终基于DevEco Studio适配HarmonyOS设备运行。

1.2 环境复用说明

本文复用前文“待办事项列表”项目的开发环境,无需重复配置。核心环境要求如下表所示,若环境未配置完成,可参考前文“前置知识与环境准备”章节完成配置:

工具名称

最低版本要求

核心作用

DevEco Studio

4.1.0.600

HarmonyOS设备适配、项目编译运行

Flutter SDK

3.16.0

构建统一风格的天气查询UI界面

Dart SDK

3.2.0

编写Flutter业务逻辑与网络请求代码

HarmonyOS SDK

API Version 9

保障应用在HarmonyOS手机/模拟器正常运行

二、项目初始化与依赖配置

2.1 新建Flutter项目

  1. 打开DevEco Studio,选择File > New > New Flutter Project,选择“Flutter Application”,点击“Next”。

  2. 配置项目信息:Project Name设为“flutter_harmony_weather”,Package Name遵循HarmonyOS规范(如“com.example.flutterharmonyweather”),选择项目保存路径后点击“Finish”。

2.2 核心依赖配置

项目需引入网络请求、JSON解析相关依赖,修改pubspec.yaml文件,在dependencies节点下添加以下配置:

dependencies: flutter: sdk: flutter http: ^0.13.5 # 用于发送网络请求获取天气数据 json_annotation: ^4.8.1 # 用于JSON数据模型序列化/反序列化 flutter_harmony: ^0.1.0 # 保障Flutter与HarmonyOS兼容性 dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.4.4 # 生成JSON解析相关代码 json_serializable: ^6.7.0 # 配合json_annotation实现JSON解析

配置完成后,在终端执行flutter pub get拉取依赖,确保无依赖冲突。

三、核心功能实现

3.1 天气数据模型定义

选择“聚合数据”免费天气API(需提前注册获取API密钥),API返回数据包含城市、温度、天气状况等信息。在lib/models/weather_model.dart中定义数据模型,代码如下:

import 'package:json_annotation/json_annotation.dart'; // 生成的解析代码会在该路径下,需先执行build_runner命令 part 'weather_model.g.dart'; @JsonSerializable() class WeatherResponse { final int error_code; // 错误码,0表示成功 final String reason; // 提示信息 final WeatherResult result; WeatherResponse({ required this.error_code, required this.reason, required this.result, }); // 从JSON转换为模型对象 factory WeatherResponse.fromJson(Map<String, dynamic> json) = _$WeatherResponseFromJson; // 从模型对象转换为JSON Map<String, dynamic> toJson() = _$WeatherResponseToJson; } @JsonSerializable() class WeatherResult { final String city; // 城市名称 final RealTimeWeather realtime; // 实时天气信息 WeatherResult({required this.city, required this.realtime}); factory WeatherResult.fromJson(Map<String, dynamic> json) = _$WeatherResultFromJson; Map<String, dynamic> toJson() = _$WeatherResultToJson; } @JsonSerializable() class RealTimeWeather { final String info; // 天气状况(如晴、阴) final String temperature; // 实时温度 final String humidity; // 湿度 final String direct; // 风向 final String power; // 风力 RealTimeWeather({ required this.info, required this.temperature, required this.humidity, required this.direct, required this.power, }); factory RealTimeWeather.fromJson(Map<String, dynamic> json) = _$RealTimeWeatherFromJson; Map<String, dynamic> toJson() = _$RealTimeWeatherToJson; }

执行flutter pub run build_runner build生成JSON解析代码(即weather_model.g.dart),若后续修改模型,需重新执行该命令。

3.2 网络请求工具类实现

lib/utils/network_utils.dart中封装网络请求工具类,统一处理请求发送与异常捕获:

import 'dart:convert'; import 'package:http/http.dart' as http; import '../models/weather_model.dart'; class NetworkUtils { // 聚合数据天气API地址(替换为自己的API密钥) static const String _weatherApiUrl = "http://v.juhe.cn/weather/index?format=2&key=YOUR_API_KEY&cityname="; // 根据城市名称查询天气 static Future<WeatherResponse?> fetchWeather(String cityName) async { try { final response = await http.get(Uri.parse(_weatherApiUrl + cityName)); if (response.statusCode == 200) { // 解析JSON数据为模型对象 return WeatherResponse.fromJson(json.decode(response.body)); } else { print("网络请求失败,状态码:${response.statusCode}"); return null; } } catch (e) { print("网络请求异常:$e"); return null; } } }

注意:将YOUR_API_KEY替换为自己在聚合数据平台获取的天气API密钥。

3.3 主页面UI与业务逻辑实现

lib/main.dart中实现天气查询主页面,包含城市输入框、查询按钮、天气信息展示区域,以及加载状态与异常提示:

import 'package:flutter/material.dart'; import 'models/weather_model.dart'; import 'utils/network_utils.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter-Harmony天气查询', theme: ThemeData(primarySwatch: Colors.blue), home: const WeatherQueryPage(), ); } } class WeatherQueryPage extends StatefulWidget { const WeatherQueryPage({super.key}); @override State<WeatherQueryPage> createState() => _WeatherQueryPageState(); } class _WeatherQueryPageState extends State<WeatherQueryPage> { final TextEditingController _cityController = TextEditingController(); WeatherResult? _weatherResult; // 存储查询到的天气结果 bool _isLoading = false; // 加载状态标识 String _errorMsg = ""; // 错误提示信息 // 查询天气方法 void _queryWeather() { final cityName = _cityController.text.trim(); if (cityName.isEmpty) { setState(() { _errorMsg = "请输入城市名称"; _weatherResult = null; }); return; } setState(() { _isLoading = true; _errorMsg = ""; }); // 调用网络工具类查询天气 NetworkUtils.fetchWeather(cityName).then((response) { setState(() { _isLoading = false; if (response != null && response.error_code == 0) { _weatherResult = response.result; } else { _errorMsg = response?.reason ?? "查询失败,请重试"; _weatherResult = null; } }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('简易天气查询')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ // 城市输入框与查询按钮 Row( children: [ Expanded( child: TextField( controller: _cityController, decoration: const InputDecoration( hintText: '请输入城市名称(如北京)', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 10), ElevatedButton( onPressed: _isLoading ? null : _queryWeather, child: _isLoading ? const CircularProgressIndicator(color: Colors.white, strokeWidth: 2) : const Text('查询'), ), ], ), const SizedBox(height: 20), // 错误提示 if (_errorMsg.isNotEmpty) Text( _errorMsg, style: const TextStyle(color: Colors.red, fontSize: 14), ), // 天气信息展示区域 if (_weatherResult != null) Expanded( child: Card( elevation: 5, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '城市:${_weatherResult!.city}', style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 20), Text('天气状况:${_weatherResult!.realtime.info}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('实时温度:${_weatherResult!.realtime.temperature}℃', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('湿度:${_weatherResult!.realtime.humidity}%', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('风向:${_weatherResult!.realtime.direct}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('风力:${_weatherResult!.realtime.power}级', style: const TextStyle(fontSize: 16)), ], ), ), ), ), ], ), ), ); } }

3.4 HarmonyOS适配配置

修改harmony/src/main/config.json文件,配置应用基本信息与设备支持类型,确保适配HarmonyOS设备:

{ "app": { "bundleName": "com.example.flutterharmonyweather", "vendor": "example", "version": { "code": 1000000, "name": "1.0.0" } }, "module": { "package": "com.example.flutterharmonyweather", "name": ".MainApplication", "mainAbility": "com.example.flutterharmonyweather.MainAbility", "deviceType": ["phone"], // 支持手机设备 "distro": { "deliveryWithInstall": true, "moduleName": "flutter_harmony_weather", "moduleType": "entry", "installationFree": false }, "abilities": [ { "name": "com.example.flutterharmonyweather.MainAbility", "label": "天气查询工具", "icon": "$media:icon", "description": "$string:mainability_description", "skills": [ { "entities": ["entity.system.home"], "actions": ["action.system.home"] } ] } ] } }

四、项目运行与调试

4.1 运行步骤

  1. 启动HarmonyOS模拟器:打开DevEco Studio的“Device Manager”,选择Phone API 9模拟器并启动。

  2. 确认依赖已安装:终端执行flutter pub get,确保所有依赖加载完成。

  3. 选择运行设备:在DevEco Studio工具栏选择已启动的HarmonyOS模拟器。

  4. 启动项目:点击工具栏“运行”按钮(或快捷键Shift+F10),等待项目编译部署完成。

4.2 关键调试点

  1. API密钥问题:若出现“查询失败”,优先检查API密钥是否正确、是否过期,可直接在浏览器访问API地址验证密钥有效性。

  2. 网络权限:若出现网络请求失败,需确认HarmonyOS模拟器已连接网络,同时检查应用是否开启网络权限(DevEco Studio中可通过config.json添加网络权限配置)。

  3. JSON解析错误:若出现解析异常,检查API返回数据格式是否与模型定义一致,可通过print(response.body)打印返回数据进行排查。

五、项目扩展方向

本项目为基础版本,可在此基础上扩展以下功能提升应用实用性,具体扩展方向、实现方式及核心价值如下表所示:

扩展功能

实现方式

核心价值

添加城市选择器

集成flutter_picker等第三方选择器插件,预设热门城市列表,替换原有输入框

降低用户输入成本,避免因城市名称输入错误导致的查询失败

新增未来几天天气预报

调用聚合数据天气API的多日预报接口,扩展WeatherModel数据模型,新增列表展示多日数据

丰富天气信息维度,满足用户对未来天气的查询需求

数据持久化

结合HarmonyOS的Preferences组件,封装数据存储工具类,保存历史查询记录

提升用户体验,用户下次打开应用可快速查看历史查询过的城市天气

主题切换

使用Flutter的Provider状态管理工具,定义浅色/深色主题配置,添加主题切换按钮控制状态

适配不同使用场景(如夜间使用),提升应用视觉舒适度

六、总结

本文通过“简易天气查询工具”项目,进一步演示了Flutter与DevEco Studio结合开发的实战流程,重点讲解了网络请求、JSON解析、HarmonyOS应用配置等核心知识点。相比上一个待办事项项目,本项目更贴近实际应用场景,涉及第三方API调用与数据处理,能帮助开发者更好地掌握跨平台技术与HarmonyOS生态的融合技巧。

开发过程中,需重点关注环境兼容性、API调用规范性及HarmonyOS配置正确性。若遇到问题,可结合IDE日志、官方文档及社区资源排查解决,逐步提升跨平台+HarmonyOS开发的实战能力。

欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net),一起共建开源鸿蒙跨平台生态。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/21 16:45:53

编辑相似度(Edit Similarity):原理、演进与多模态扩展

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 1 引言 在人工智能与机器学习领域&#xff0c;衡量两个数据对象之间的…

作者头像 李华
网站建设 2026/9/21 17:16:34

【深度解析】MiniCPM 2.0:端侧大模型的技术性进展与技术革新

2024年9月5日&#xff0c;MiniCPM团队正式发布了备受瞩目的端侧语言大模型系列——MiniCPM 2.0的技术报告。作为一款聚焦于终端设备部署的轻量化大模型&#xff0c;MiniCPM 2.0在保持模型小巧体积的同时&#xff0c;实现了性能的跨越式提升&#xff0c;为人工智能在边缘计算领域…

作者头像 李华
网站建设 2026/9/20 16:03:54

ClickHouse 快速入门

ClickHouse 快速入门1 ClickHouse 介绍1 行式存储VS列式存储2 ClickHouse VS MySQL3 ClickHouse VS Apache Doris4 ClickHouse 的优缺点5 ClickHouse 适用的场景2 ClickHouse 安装1 镜像下载2 容器运行3 创建用户3 ClickHouse 连接1 连接2 建表测试4 SpringBoot 集成 ClickHous…

作者头像 李华
网站建设 2026/9/21 18:18:57

基于SpringBoot的人事管理系统设计与实现

基于SpringBoot的人事管理系统设计与实现 基于SpringBoot的人事管理系统&#xff1a;毕业设计优质资源全解析 在当今数字化时代&#xff0c;企业人力资源管理正经历着从传统手工操作向智能化、自动化转型的关键阶段。对于计算机科学和软件工程专业的学生而言&#xff0c;一个…

作者头像 李华
网站建设 2026/9/19 4:40:35

Day36官方文档的阅读

官方文档咋找&#xff1f; 常用渠道是项目的 GitHub 仓库&#xff08;一般会有docs文件夹&#xff09;&#xff0c;或者工具 / 框架的官方网站。 看文档的注意点 必须保证你安装的工具包版本&#xff0c;和看的文档版本一致&#xff01;不然可能出现 “文档写了 A 功能&#x…

作者头像 李华