当前位置: 首页 > news >正文

Flutter 跨平台实战:鸿蒙 6.0 (API20) 集成三方库开发天气查询应用

Flutter 跨平台实战:鸿蒙 6.0 (API20) 集成三方库开发天气查询应用

前言

对于鸿蒙开发者入门 Flutter 跨平台开发,借助成熟三方库可以快速实现复杂功能。本文以跨平台天气查询应用为案例,在鸿蒙 6.0 (API20) 环境下,集成网络请求、JSON 解析、位置获取、UI 美化三方库,完成可落地的跨端应用。

一、环境配置要求

  1. Flutter 3.16 及以上版本

  2. DevEco Studio 搭载鸿蒙 6.0 (API20) 模拟器 / 真机

  3. 开启网络权限、定位权限

  4. 代码编辑器:Android Studio / VS Code

二、项目创建与鸿蒙适配配置

1. 创建 Flutter 项目

flutter create flutter\_harmony\_weather cd flutter\_harmony\_weather

2. 鸿蒙 6.0 适配配置

修改android/app/build.gradle,匹配鸿蒙底层适配要求

android {   compileSdkVersion 33   defaultConfig {   applicationId "com.example.flutter\_harmony\_weather"   minSdkVersion 21   targetSdkVersion 33   versionCode 1   versionName "1.0"   } }

3. 权限配置

打开android/app/src/main/AndroidManifest.xml,添加权限

\<!-- 网络权限 --> \<uses-permission android:name="android.permission.INTERNET"/> \<!-- 定位权限 --> \<uses-permission android:name="android.permission.ACCESS\_FINE\_LOCATION"/> \<uses-permission android:name="android.permission.ACCESS\_COARSE\_LOCATION"/>

三、引入兼容鸿蒙的三方库

本次选用在鸿蒙 6.0 上运行稳定的常用库,在pubspec.yaml中添加依赖

dependencies: &#x20; flutter: &#x20; sdk: flutter &#x20; \# 网络请求三方库 &#x20; dio: ^5.4.0 &#x20; \# 定位获取三方库 &#x20; geolocator: ^10.1.0 &#x20; \# 加载状态提示库 &#x20; flutter\_easyloading: ^3.0.5 &#x20; \# 图标美化库 &#x20; font\_awesome\_flutter: ^10.6.0

执行依赖安装命令

flutter pub get

四、项目结构规划

lib/ ├── main.dart # 应用入口 ├── models/weather\_model.dart # 天气数据模型 ├── utils/api\_util.dart # 网络请求工具 ├── pages/weather\_page.dart # 主页面

五、代码实现

1. 天气数据模型:models/weather_model.dart

解析接口返回的 JSON 数据,结构化存储天气信息

/// 天气数据模型 class WeatherModel { &#x20; final String city; // 城市 &#x20; final String temp; // 温度 &#x20; final String weather; // 天气状况 &#x20; final String wind; // 风力 &#x20; final String humidity; // 湿度 &#x20; WeatherModel({ &#x20; required this.city, &#x20; required this.temp, &#x20; required this.weather, &#x20; required this.wind, &#x20; required this.humidity, &#x20; }); &#x20; // 解析JSON数据,此处适配简易天气接口 &#x20; factory WeatherModel.fromJson(Map\<String, dynamic> json) { &#x20; return WeatherModel( &#x20; city: json\['city'] ?? '未知城市', &#x20; temp: json\['temp'] ?? 'N/A', &#x20; weather: json\['weather'] ?? '未知天气', &#x20; wind: json\['wind'] ?? 'N/A', &#x20; humidity: json\['humidity'] ?? 'N/A', &#x20; ); &#x20; } }

2. 网络请求工具:utils/api_util.dart

基于 dio 三方库实现网络请求,封装获取天气方法

import 'package:dio/dio.dart'; import '../models/weather\_model.dart'; class ApiUtil { &#x20; final Dio \_dio = Dio(); &#x20; /// 获取指定城市天气 &#x20; Future\<WeatherModel> getWeather(String city) async { &#x20; try { &#x20; // 免费天气接口,可自行替换为正规天气API &#x20; final response = await \_dio.get( &#x20; 'https://api.example.com/weather', &#x20; queryParameters: {'city': city}, &#x20; ); &#x20; return WeatherModel.fromJson(response.data); &#x20; } catch (e) { &#x20; rethrow; &#x20; } &#x20; } }

3. 主页面实现:pages/weather_page.dart

集成定位、网络请求、加载提示三方库,实现核心交互

import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:flutter\_easyloading/flutter\_easyloading.dart'; import 'package:font\_awesome\_flutter/font\_awesome\_flutter.dart'; import '../utils/api\_util.dart'; import '../models/weather\_model.dart'; class WeatherPage extends StatefulWidget { &#x20; const WeatherPage({super.key}); &#x20; @override &#x20; State\<WeatherPage> createState() => \_WeatherPageState(); } class \_WeatherPageState extends State\<WeatherPage> { &#x20; final ApiUtil \_apiUtil = ApiUtil(); &#x20; WeatherModel? \_weatherModel; &#x20; final TextEditingController \_cityController = TextEditingController(); &#x20; @override &#x20; void initState() { &#x20; super.initState(); &#x20; // 初始化加载提示组件 &#x20; EasyLoading.init(); &#x20; } &#x20; /// 获取定位权限并定位当前城市 &#x20; Future\<void> getLocationWeather() async { &#x20; EasyLoading.show(status: '获取定位中...'); &#x20; // 检查定位权限 &#x20; bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); &#x20; if (!serviceEnabled) { &#x20; EasyLoading.showError('定位服务未开启'); &#x20; return; &#x20; } &#x20; LocationPermission permission = await Geolocator.checkPermission(); &#x20; if (permission == LocationPermission.denied) { &#x20; permission = await Geolocator.requestPermission(); &#x20; if (permission == LocationPermission.denied) { &#x20; EasyLoading.showError('定位权限被拒绝'); &#x20; return; &#x20; } &#x20; } &#x20; if (permission == LocationPermission.deniedForever) { &#x20; EasyLoading.showError('权限永久拒绝,无法定位'); &#x20; return; &#x20; } &#x20; // 获取定位坐标,实际开发可通过经纬度获取城市 &#x20; Position position = await Geolocator.getCurrentPosition(); &#x20; await getWeatherData('北京'); &#x20; } &#x20; /// 获取天气数据 &#x20; Future\<void> getWeatherData(String city) async { &#x20; if (city.isEmpty) { &#x20; EasyLoading.showInfo('请输入城市名称'); &#x20; return; &#x20; } &#x20; EasyLoading.show(status: '加载天气中...'); &#x20; try { &#x20; final data = await \_apiUtil.getWeather(city); &#x20; setState(() { &#x20; \_weatherModel = data; &#x20; }); &#x20; EasyLoading.showSuccess('加载成功'); &#x20; } catch (e) { &#x20; EasyLoading.showError('获取天气失败:\${e.toString()}'); &#x20; } &#x20; } &#x20; @override &#x20; Widget build(BuildContext context) { &#x20; return Scaffold( &#x20; appBar: AppBar( &#x20; title: const Text('Flutter鸿蒙天气查询'), &#x20; centerTitle: true, &#x20; ), &#x20; body: SingleChildScrollView( &#x20; padding: const EdgeInsets.all(20), &#x20; child: Column( &#x20; children: \[ &#x20; // 城市输入框 &#x20; TextField( &#x20; controller: \_cityController, &#x20; decoration: InputDecoration( &#x20; hintText: '请输入城市名称', &#x20; suffixIcon: IconButton( &#x20; icon: const Icon(Icons.search), &#x20; onPressed: () { &#x20; getWeatherData(\_cityController.text.trim()); &#x20; }, &#x20; ), &#x20; border: const OutlineInputBorder(), &#x20; ), &#x20; ), &#x20; const SizedBox(height: 15), &#x20; // 定位获取天气按钮 &#x20; ElevatedButton.icon( &#x20; onPressed: getLocationWeather, &#x20; icon: const FaIcon(FontAwesomeIcons.locationCrosshairs), &#x20; label: const Text('定位获取当前天气'), &#x20; ), &#x20; const SizedBox(height: 30), &#x20; // 天气信息展示区域 &#x20; if (\_weatherModel != null) &#x20; Card( &#x20; elevation: 5, &#x20; shape: RoundedRectangleBorder( &#x20; borderRadius: BorderRadius.circular(15), &#x20; ), &#x20; child: Padding( &#x20; padding: const EdgeInsets.all(25), &#x20; child: Column( &#x20; children: \[ &#x20; Text( &#x20; \_weatherModel!.city, &#x20; style: const TextStyle( &#x20; fontSize: 24, fontWeight: FontWeight.bold), &#x20; ), &#x20; const SizedBox(height: 20), &#x20; Text( &#x20; '\${\_weatherModel!.temp}℃', &#x20; style: const TextStyle(fontSize: 40), &#x20; ), &#x20; const SizedBox(height: 10), &#x20; Text( &#x20; \_weatherModel!.weather, &#x20; style: const TextStyle(fontSize: 20), &#x20; ), &#x20; const Divider(height: 30), &#x20; Row( &#x20; mainAxisAlignment: MainAxisAlignment.spaceAround, &#x20; children: \[ &#x20; \_weatherItem( &#x20; FontAwesomeIcons.wind, &#x20; '风力', &#x20; \_weatherModel!.wind, &#x20; ), &#x20; \_weatherItem( &#x20; FontAwesomeIcons.droplet, &#x20; '湿度', &#x20; \_weatherModel!.humidity, &#x20; ), &#x20; ], &#x20; ), &#x20; ], &#x20; ), &#x20; ), &#x20; ), &#x20; ], &#x20; ), &#x20; ), &#x20; ); &#x20; } &#x20; /// 天气信息子项 &#x20; Widget \_weatherItem(IconData icon, String title, String value) { &#x20; return Column( &#x20; children: \[ &#x20; FaIcon(icon, size: 25), &#x20; const SizedBox(height: 5), &#x20; Text(title), &#x20; Text(value), &#x20; ], &#x20; ); &#x20; } }

4. 应用入口:main.dart

全局配置加载提示,挂载主页面

import 'package:flutter/material.dart'; import 'package:flutter\_easyloading/flutter\_easyloading.dart'; import 'pages/weather\_page.dart'; void main() { &#x20; runApp(const MyApp()); } class MyApp extends StatelessWidget { &#x20; const MyApp({super.key}); &#x20; @override &#x20; Widget build(BuildContext context) { &#x20; return MaterialApp( &#x20; title: 'Flutter鸿蒙天气', &#x20; theme: ThemeData(primarySwatch: Colors.blue), &#x20; home: const WeatherPage(), &#x20; // 配置加载提示三方库 &#x20; builder: EasyLoading.init(), &#x20; debugShowCheckedModeBanner: false, &#x20; ); &#x20; } }

六、鸿蒙 6.0 (API20) 运行步骤

  1. 启动 DevEco Studio 中鸿蒙 6.0 API20 模拟器

  2. 连接设备后执行运行命令

flutter run
  1. 授予应用定位、网络权限

  2. 输入城市或使用定位功能获取天气信息

七、三方库在鸿蒙平台的使用说明

  1. dio:网络请求无兼容问题,可正常请求天气接口

  2. geolocator:适配鸿蒙定位服务,可成功获取设备位置

  3. flutter_easyloading:加载弹窗在鸿蒙设备渲染正常

  4. font_awesome_flutter:矢量图标完美展示

八、开发注意事项

  1. 正式开发需替换为合规商用天气 API,替换接口地址即可

  2. 鸿蒙设备需手动开启应用权限,否则定位功能无法使用

  3. 网络请求需处理异常情况,提升应用稳定性

九、总结

本项目完整展示了Flutter 结合三方库开发鸿蒙 6.0 应用的全流程,贴合实际开发场景。借助 Flutter 跨平台特性,一套代码可同时运行在 Android、iOS、鸿蒙设备上,大幅降低鸿蒙应用开发成本。

http://www.cnnetsun.cn/news/1778804.html

相关文章:

  • 图解Floyd判圈算法 | 从龟兔赛跑到Java实战,一文学会环检测与定位
  • OpenClaw备份策略:Gemma-3-12b-it自动化管理NAS存储
  • 打造可交付的上位机实战项目
  • 【软件部署】docker快速部署MySQL多个主版本的单实例
  • Cursor+AI开发实战:解决npm安装electron卡死的3个关键技巧(附国内镜像配置)
  • Unity游戏插件加载革命:MelonLoader全方位技术指南
  • 绝区零一条龙:智能游戏助手提升效率指南
  • 别再用免费推客系统,坑多还不安全
  • 从LaTeX论文中提取关键思想:nlp_structbert辅助学术文献综述
  • 解决微信聊天记录备份难题:WeChatExporter工具的技术实现与应用
  • PMP刷题必备口诀-3(题库+答案详细解析)
  • PMP刷题必备口诀-2(题库+答案详细解析)
  • nlp_structbert_sentence-similarity_chinese-large惊艳效果:古汉语白话转译语义匹配(‘吾甚悦之’vs‘我很喜欢’)
  • 实测好用!cv_resnet18_ocr-detection文字检测WebUI体验分享
  • 如何用三月七小助手实现《崩坏:星穹铁道》全自动游戏体验
  • Mac屏幕录制全攻略:从自带工具到专业软件
  • 2026重庆渗漏水维修:卫生间与屋顶频发?选择正规防水工艺、专业施工流程、本地企业评测指南
  • RT-Thread动态内存堆管理:小内存算法优化与API接口实战
  • 3步解密RePKG:Wallpaper Engine资源提取与格式转换的深度实战指南
  • 系统测试测什么/怎么测
  • 浏览器自动化之王:OpenClaw+Qwen3.5-9B实现复杂表单填充
  • 基于Python的党员学习交流平台毕设源码
  • 如何用md2pptx实现Markdown到演示文稿的高效转换
  • Z-Image-Turbo-辉夜巫女快速部署:5分钟搭建专属AI画师,一键生成日系巫女图
  • SMUDebugTool终极指南:如何深度优化Ryzen系统性能的完整教程
  • Kandinsky-5.0-I2V-Lite-5s社区作品巡礼:开发者创意应用案例集
  • 从PID到MPC:自动驾驶路径跟踪算法的演进与实战对比
  • Cesium 1.97版本后,如何自己动手实现模型实例化绘制(附完整代码)
  • 使用AI辅助写设计文档的感受与一些经验总结
  • 郭老师-寒门难出贵子?真相与破局之道