Flutter 集成三方库开发鸿蒙6.0+(SDK API20+)跨端天气应用
本文围绕 Flutter、三方库与鸿蒙三大核心要素,详细阐述了一款可运行于鸿蒙6.0及以上系统(SDK API20+)的跨端天气应用开发全流程。项目基于 Flutter 框架,集成 http、shared_preferences 等常用三方库,采用 MVVM 架构,完成了从环境搭建、三方库集成、核心功能开发到鸿蒙适配、打包调试的完整实现,同时提供了常见问题排查方案与优化方向,助力开发者快速掌握 F
Flutter 集成三方库开发鸿蒙6.0+(SDK API20+)跨端天气应用
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
一、项目概述
本项目面向鸿蒙开发者,基于 Flutter 框架,结合鸿蒙生态三方库,从零搭建一款可运行于鸿蒙6.0及以上系统(SDK API20+)的跨端天气应用,完整覆盖环境配置、三方库集成、鸿蒙适配、功能开发全流程,帮助开发者快速掌握 Flutter 结合三方库开发鸿蒙应用的核心实践。
二、前置环境准备
2.1 环境要求
-
操作系统:Windows 10+/macOS 12+/Linux(推荐 Windows,适配鸿蒙开发工具)
-
Flutter 版本:3.13.0 及以上(需支持鸿蒙 ArkUI 适配)
-
鸿蒙开发环境:DevEco Studio 4.0 及以上,配置鸿蒙 SDK(API 20+,对应鸿蒙6.0及以上系统)
-
Dart 版本:3.1.0 及以上(与 Flutter 版本匹配)
-
网络环境:可正常访问 Flutter 包管理仓库(pub.dev)
2.2 环境配置步骤
- 安装 Flutter
# 1. 下载 Flutter SDK(鸿蒙适配版,官方已原生支持鸿蒙)
# 官网:https://flutter.dev/docs/get-started/install
# 2. 配置环境变量(Windows 示例)
# 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」
# 在「系统变量」的 Path 中添加 Flutter 安装目录下的 bin 文件夹
# 3. 验证安装
flutter doctor
执行 flutter doctor 后,确保所有检查项通过(需安装 Android Studio/Xcode 用于移动端调试,鸿蒙端需 DevEco Studio)。
- 配置鸿蒙开发环境
-
安装 DevEco Studio:https://developer.harmonyos.com/cn/develop/deveco-studio
-
打开 DevEco Studio,安装鸿蒙 SDK(API 20 及以上,对应鸿蒙6.0+系统),配置签名文件(用于真机调试)
-
执行
flutter devices,确保鸿蒙设备/模拟器被识别(设备需为鸿蒙6.0及以上版本)
- 创建 Flutter 项目
# 1. 执行创建命令
flutter create flutter_harmony_weather
# 2. 进入项目目录
cd flutter_harmony_weather
# 3. 打开项目(VS Code/Android Studio/DevEco Studio 均可)
code .
三、三方库选型与集成
3.1 核心三方库介绍
| 库名 | 用途 | 版本 | 适配鸿蒙(6.0+,API20+) |
|---|---|---|---|
| http | 网络请求,调用天气API | ^1.1.0 | ✅ 原生支持 |
| shared_preferences | 本地存储,缓存城市/主题配置 | ^2.2.2 | ✅ 鸿蒙适配 |
| flutter_screenutil | 屏幕适配,统一多端尺寸 | ^5.9.0 | ✅ 鸿蒙适配 |
| flutter_spinkit | 加载动画,提升交互体验 | ^5.2.0 | ✅ 原生支持 |
| path_provider | 文件路径管理(可选,用于缓存天气数据) | ^2.1.1 | ✅ 鸿蒙适配 |
3.2 集成三方库步骤
- 配置
pubspec.yaml
打开项目根目录的 pubspec.yaml,在 dependencies 节点添加以下依赖:
name: flutter_harmony_weather
description: A Flutter weather app for HarmonyOS 6.0+.
version: 1.0.0+1
environment:
sdk: '>=3.1.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
# 网络请求
http: ^1.1.0
# 本地存储
shared_preferences: ^2.2.2
# 屏幕适配
flutter_screenutil: ^5.9.0
# 加载动画
flutter_spinkit: ^5.2.0
# 文件路径(可选)
path_provider: ^2.1.1
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
- 安装依赖
# 执行命令安装所有三方库
flutter pub get
执行完成后,依赖会自动下载并集成到项目中,确保所有三方库均适配鸿蒙6.0+(API20+)系统。
四、项目架构设计
采用 MVVM 架构,分层清晰,便于维护和后续拓展,适配鸿蒙6.0+跨端开发需求:
-
Model 层:定义天气数据实体、API 接口
-
ViewModel 层:处理业务逻辑、网络请求、数据缓存
-
View 层:UI 界面,绑定 ViewModel 数据,响应用户交互,适配鸿蒙多设备显示
-
Utils 层:工具类(屏幕适配、时间格式化等)
五、核心功能开发(含完整代码+注释)
5.1 Model 层:定义天气数据实体
创建 lib/models/weather_model.dart,定义天气数据结构:
// lib/models/weather_model.dart
/// 天气数据实体类
class WeatherModel {
// 城市名称
final String city;
// 温度(摄氏度)
final double temperature;
// 天气描述(如:晴、多云)
final String description;
// 天气图标代码(用于加载图标)
final String icon;
// 湿度(百分比)
final int humidity;
// 风速(km/h)
final double windSpeed;
// 构造函数
WeatherModel({
required this.city,
required this.temperature,
required this.description,
required this.icon,
required this.humidity,
required this.windSpeed,
});
// 从JSON解析数据(网络请求返回的JSON转实体)
factory WeatherModel.fromJson(Map<String, dynamic> json) {
return WeatherModel(
city: json['name'] ?? '未知城市',
temperature: (json['main']['temp'] - 273.15), // 开尔文转摄氏度
description: json['weather'][0]['description'] ?? '未知天气',
icon: json['weather'][0]['icon'] ?? '01d',
humidity: json['main']['humidity'] ?? 0,
windSpeed: (json['wind']['speed'] * 3.6), // m/s 转 km/h
);
}
}
5.2 ViewModel 层:网络请求与业务逻辑
创建 lib/view_models/weather_view_model.dart,处理网络请求、数据缓存:
// lib/view_models/weather_view_model.dart
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../models/weather_model.dart';
/// 天气业务逻辑 ViewModel
class WeatherViewModel extends ChangeNotifier {
// 天气数据
WeatherModel? _weather;
// 加载状态
bool _isLoading = false;
// 错误信息
String? _errorMessage;
// getter 方法,供 View 层访问
WeatherModel? get weather => _weather;
bool get isLoading => _isLoading;
String? get errorMessage => _errorMessage;
// 天气API(使用 OpenWeatherMap 免费API,需自行申请Key:https://openweathermap.org/api)
static const String _apiKey = 'YOUR_API_KEY'; // 替换为你的API Key
static const String _baseUrl = 'https://api.openweathermap.org/data/2.5/weather';
/// 根据城市名获取天气
Future<void> fetchWeather(String city) async {
// 1. 设置加载状态,通知UI更新
_isLoading = true;
_errorMessage = null;
notifyListeners();
try {
// 2. 发起网络请求
final response = await http.get(
Uri.parse('$_baseUrl?q=$city&appid=$_apiKey'),
);
// 3. 检查响应状态
if (response.statusCode == 200) {
// 4. 解析JSON数据
final jsonData = json.decode(response.body);
_weather = WeatherModel.fromJson(jsonData);
// 5. 缓存城市到本地(下次打开自动加载)
await _saveCityToPrefs(city);
} else {
// 6. 处理请求失败
_errorMessage = '获取天气失败:${response.statusCode}';
}
} catch (e) {
// 7. 捕获异常
_errorMessage = '网络异常:$e';
} finally {
// 8. 结束加载状态,通知UI更新
_isLoading = false;
notifyListeners();
}
}
/// 从本地缓存加载上次查询的城市
Future<void> loadLastCity() async {
final prefs = await SharedPreferences.getInstance();
final lastCity = prefs.getString('last_city') ?? '北京'; // 默认北京
await fetchWeather(lastCity);
}
/// 保存城市到本地缓存
Future<void> _saveCityToPrefs(String city) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('last_city', city);
}
}
注意:
_apiKey需要自行到 OpenWeatherMap 官网申请免费密钥,替换后才能正常请求数据,该配置适配鸿蒙6.0+系统网络请求规范。
5.3 View 层:UI 界面开发
5.3.1 主页面:lib/screens/weather_screen.dart
// lib/screens/weather_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:provider/provider.dart';
import '../view_models/weather_view_model.dart';
/// 天气主页面(适配鸿蒙6.0+多设备)
class WeatherScreen extends StatefulWidget {
const WeatherScreen({super.key});
State<WeatherScreen> createState() => _WeatherScreenState();
}
class _WeatherScreenState extends State<WeatherScreen> {
// 城市输入控制器
final TextEditingController _cityController = TextEditingController();
void initState() {
super.initState();
// 页面初始化时,加载上次缓存的城市天气
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<WeatherViewModel>(context, listen: false).loadLastCity();
});
}
void dispose() {
// 销毁控制器,防止内存泄漏
_cityController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
// 初始化屏幕适配(鸿蒙6.0+手机、平板、智慧屏等多端统一)
ScreenUtil.init(context, designSize: const Size(360, 690));
return Scaffold(
// 渐变背景
backgroundColor: Colors.blue[50],
appBar: AppBar(
title: const Text('Flutter 鸿蒙天气'),
centerTitle: true,
backgroundColor: Colors.blue[400],
),
body: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
// 1. 城市输入框
_buildCityInput(),
SizedBox(height: 20.h),
// 2. 天气展示区域
Expanded(child: _buildWeatherContent()),
],
),
),
);
}
/// 城市输入组件
Widget _buildCityInput() {
return TextField(
controller: _cityController,
decoration: InputDecoration(
hintText: '请输入城市名(如:北京、Shanghai)',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.r),
),
suffixIcon: IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// 点击搜索按钮,获取天气
final city = _cityController.text.trim();
if (city.isNotEmpty) {
Provider.of<WeatherViewModel>(context, listen: false)
.fetchWeather(city);
}
},
),
),
// 点击键盘完成按钮,触发搜索
onSubmitted: (value) {
if (value.isNotEmpty) {
Provider.of<WeatherViewModel>(context, listen: false)
.fetchWeather(value);
}
},
);
}
/// 天气内容展示组件
Widget _buildWeatherContent() {
return Consumer<WeatherViewModel>(
builder: (context, viewModel, child) {
// 1. 加载中状态
if (viewModel.isLoading) {
return Center(
child: SpinKitFadingCircle(
color: Colors.blue[400],
size: 50.w,
),
);
}
// 2. 错误状态
if (viewModel.errorMessage != null) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error_outline, size: 60.w, color: Colors.red),
SizedBox(height: 16.h),
Text(
viewModel.errorMessage!,
style: TextStyle(fontSize: 16.sp, color: Colors.red),
textAlign: TextAlign.center,
),
SizedBox(height: 16.h),
ElevatedButton(
onPressed: () {
viewModel.loadLastCity();
},
child: const Text('重试'),
),
],
),
);
}
// 3. 正常数据状态
final weather = viewModel.weather;
if (weather == null) {
return const Center(child: Text('暂无天气数据'));
}
return SingleChildScrollView(
child: Column(
children: [
// 城市名
Text(
weather.city,
style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.bold,
color: Colors.blue[800],
),
),
SizedBox(height: 20.h),
// 天气图标(OpenWeatherMap 图标)
Image.network(
'https://openweathermap.org/img/wn/${weather.icon}@2x.png',
width: 100.w,
height: 100.h,
),
SizedBox(height: 10.h),
// 温度
Text(
'${weather.temperature.toStringAsFixed(1)}°C',
style: TextStyle(
fontSize: 48.sp,
fontWeight: FontWeight.bold,
color: Colors.blue[700],
),
),
SizedBox(height: 10.h),
// 天气描述
Text(
weather.description,
style: TextStyle(
fontSize: 20.sp,
color: Colors.blue[600],
),
),
SizedBox(height: 30.h),
// 详细信息卡片
Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.r),
),
child: Padding(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
// 湿度
_buildDetailRow(
icon: Icons.water_drop,
title: '湿度',
value: '${weather.humidity}%',
),
SizedBox(height: 16.h),
// 风速
_buildDetailRow(
icon: Icons.air,
title: '风速',
value: '${weather.windSpeed.toStringAsFixed(1)} km/h',
),
],
),
),
),
],
),
);
},
);
}
/// 详细信息行组件
Widget _buildDetailRow({
required IconData icon,
required String title,
required String value,
}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(icon, color: Colors.blue[400], size: 24.w),
SizedBox(width: 8.w),
Text(
title,
style: TextStyle(fontSize: 16.sp, color: Colors.grey[700]),
),
],
),
Text(
value,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Colors.blue[800],
),
),
],
);
}
}
5.3.2 主入口:lib/main.dart
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'screens/weather_screen.dart';
import 'view_models/weather_view_model.dart';
void main() {
runApp(
// 注入 ViewModel,全局共享状态(适配鸿蒙6.0+系统运行规范)
ChangeNotifierProvider(
create: (context) => WeatherViewModel(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 鸿蒙天气',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
// 鸿蒙6.0+多端自适应主题
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: const WeatherScreen(),
// 关闭调试标签
debugShowCheckedModeBanner: false,
);
}
}
六、鸿蒙适配与打包(适配6.0+,SDK API20+)
6.1 鸿蒙专属配置
- 配置鸿蒙项目文件
Flutter 会自动生成鸿蒙项目目录 ohos/,无需手动修改核心配置,只需确保以下两点(适配鸿蒙6.0+系统):
-
ohos/entry/src/main/module.json5中权限配置正确(网络权限) -
SDK 版本配置为 API20+,对应鸿蒙6.0及以上系统
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
"compileSdkVersion": 20,
"compatibleSdkVersion": 20
}
}
- 鸿蒙多设备适配
已通过 flutter_screenutil 实现屏幕适配,自动适配鸿蒙6.0+系统的手机、平板、智慧屏等多类设备,确保UI显示一致。
6.2 运行与调试
- 连接鸿蒙设备/启动模拟器
-
真机:开启开发者模式、USB调试,连接电脑(设备需为鸿蒙6.0及以上版本)
-
模拟器:DevEco Studio 中启动鸿蒙6.0+模拟器(SDK API20+)
- 运行项目
# 直接运行到鸿蒙设备(6.0+)
flutter run -d harmony
执行后,Flutter 会自动编译并安装到鸿蒙6.0+设备,完成调试。
6.3 打包鸿蒙应用
# 1. 构建鸿蒙安装包(.hap),适配6.0+系统
flutter build hap --release
# 2. 打包完成后,安装包路径:
# build/harmony/ohos/build/outputs/hap/release/entry-release.hap
可通过 DevEco Studio 对 hap 包进行签名,发布到鸿蒙应用市场(需符合鸿蒙6.0+应用发布规范)。
七、项目优化与拓展
7.1 优化方向
-
性能优化:添加网络请求缓存、图片懒加载、列表预渲染,适配鸿蒙6.0+系统性能要求
-
功能拓展:添加7天天气预报、城市管理、主题切换、通知提醒
-
鸿蒙特性适配:集成鸿蒙原子化服务、卡片、分布式能力(适配鸿蒙6.0+新特性)
-
三方库拓展:集成
flutter_local_notifications实现天气提醒,geolocator实现定位获取天气(确保三方库适配鸿蒙6.0+)
7.2 常见问题排查
| 问题 | 解决方案 |
|---|---|
| 网络请求失败 | 检查 API Key 是否正确、网络是否通畅、鸿蒙网络权限是否开启,确认设备为鸿蒙6.0+版本 |
| 鸿蒙设备无法识别 | 执行 flutter devices 检查,重新连接设备/重启 ADB,确保设备系统版本≥6.0 |
| 三方库集成失败 | 执行 flutter pub cache repair 修复缓存,重新 flutter pub get,确认三方库适配鸿蒙6.0+(API20+) |
| 屏幕适配异常 | 确保 ScreenUtil.init 在页面构建时正确初始化,适配鸿蒙6.0+多设备尺寸 |
| 打包失败 | 检查 SDK 版本是否配置为 API20+,确认签名文件配置正确,符合鸿蒙6.0+打包规范 |
八、项目总结
本项目基于 Flutter 框架,集成 http、shared_preferences 等三方库,完成了一款可运行于鸿蒙6.0及以上系统(SDK API20+)的跨端天气应用开发,覆盖了从环境搭建、三方库集成、业务开发到鸿蒙打包的全流程。
通过本项目,可掌握以下核心内容:
-
Flutter 结合三方库开发鸿蒙6.0+应用的完整流程
-
常用 Flutter 三方库的集成与鸿蒙适配方法
-
MVVM 架构在 Flutter 鸿蒙跨端项目中的实践
-
鸿蒙6.0+(SDK API20+)系统的适配、调试与打包技巧
九、附录:项目结构
flutter_harmony_weather/
├── lib/
│ ├── models/
│ │ └── weather_model.dart # 数据实体
│ ├── screens/
│ │ └── weather_screen.dart # 主页面
│ ├── view_models/
│ │ └── weather_view_model.dart # 业务逻辑
│ └── main.dart # 入口文件
├── ohos/ # 鸿蒙项目目录(自动生成,适配API20+)
├── pubspec.yaml # 依赖配置
└── README.md # 项目说明
运行效果

更多推荐


所有评论(0)