Flutter 集成三方库实现鸿蒙 6.0 + 天气查询 App 实战
本篇带你使用 Flutter + 常用三方库,开发一个可在 鸿蒙 6.0 及以上版本(API20+) 运行的天气查询 App,包含:城市天气查询、实时温度显示、天气状态图标、本地缓存查询记录、鸿蒙风格 UI 等完整功能。本项目使用 Flutter + 3 个高频三方库,实现了可在 鸿蒙 6.0+(API20+) 运行的跨端天气查询应用,全程遵循新手友好原则,无复杂配置、无需申请接口密钥,代码带详细
关键词:Flutter、三方库、鸿蒙、鸿蒙 6.0、API20+、跨端开发、实战项目
前言
作为鸿蒙开发者,学习 Flutter 跨端开发能让你一套代码运行在鸿蒙、安卓、iOS 等多平台。本篇带你使用 Flutter + 常用三方库,开发一个可在 鸿蒙 6.0 及以上版本(API20+) 运行的天气查询 App,包含:城市天气查询、实时温度显示、天气状态图标、本地缓存查询记录、鸿蒙风格 UI 等完整功能。
项目简单、实用、可直接上线,非常适合新手入门,且与之前的备忘录、计算器、图片、待办、记账项目完全无重复。
一、项目介绍
项目名称
Flutter 鸿蒙天气查询应用
核心功能
输入城市名称,查询实时天气
显示实时温度、天气状态(晴、雨、多云等)
本地缓存查询历史(关闭 APP 不丢失)
点击历史记录,快速重新查询
删除单条 / 全部查询历史
适配鸿蒙 6.0 + 系统风格、不同屏幕尺寸
网络异常提示、查询失败反馈
用到的三方库(3 个高频实用库)
shared_preferences:本地数据持久化(缓存查询历史,鸿蒙 6.0 + 完美兼容)
fluttertoast:操作提示弹窗(查询结果、删除反馈、网络提示,适配鸿蒙弹窗风格)
dio:网络请求库(请求天气接口,获取实时天气数据,鸿蒙 6.0 + 支持)
运行平台
鸿蒙 6.0+ 设备 / 模拟器(API Level ≥20)
二、环境准备
Flutter SDK(3.10+)
VS Code / Android Studio
鸿蒙 6.0+ 模拟器或真机(API20+)
开启鸿蒙设备开发者模式 + USB 调试
联网环境(用于请求天气接口)
import ‘package:flutter/material.dart’;
// 导入三方库1:本地存储(缓存查询历史)
import ‘package:shared_preferences/shared_preferences.dart’;
// 导入三方库2:操作提示弹窗
import ‘package:fluttertoast/fluttertoast.dart’;
// 导入三方库3:网络请求(请求天气接口)
import ‘package:dio/dio.dart’;
// 天气数据模型:规范天气数据格式,便于管理和使用
class WeatherModel {
String city; // 城市名称
double temp; // 实时温度(单位:℃)
String weather; // 天气状态(晴、多云、雨等)
String updateTime; // 更新时间
// 构造方法:初始化天气数据
WeatherModel({
required this.city,
required this.temp,
required this.weather,
required this.updateTime,
});
// 从接口返回的JSON数据,转成WeatherModel对象(核心方法)
static WeatherModel fromJson(Map<String, dynamic> json) {
return WeatherModel(
city: json[‘city’] ?? ‘’,
temp: json[‘temp’] != null ? double.parse(json[‘temp’]) : 0.0,
weather: json[‘weather’] ?? ‘未知’,
updateTime: json[‘updateTime’] ?? ‘’,
);
}
}
// 程序入口:Flutter应用启动时首先执行
void main() {
runApp(const MyApp());
}
// 根组件(无状态组件,鸿蒙6.0+界面渲染入口)
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Flutter鸿蒙天气查询’,
// 适配鸿蒙6.0+系统的主题色,符合鸿蒙设计规范
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: ‘HarmonyOS Sans’, // 适配鸿蒙系统默认字体
brightness: Brightness.light,
),
darkTheme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: ‘HarmonyOS Sans’,
brightness: Brightness.dark,
),
// 关闭调试标签(发布时必须关闭,开发时可保留)
debugShowCheckedModeBanner: false,
// 应用首页为天气查询主页面
home: const WeatherQueryPage(),
);
}
}
// 天气查询主页面(有状态组件,处理核心业务逻辑)
class WeatherQueryPage extends StatefulWidget {
const WeatherQueryPage({super.key});
@override
State createState() => _WeatherQueryPageState();
}
class _WeatherQueryPageState extends State {
// 输入框控制器:获取用户输入的城市名称
final TextEditingController _cityController = TextEditingController();
// 天气数据:存储当前查询到的天气信息
WeatherModel? _currentWeather;
// 查询历史列表:存储用户查询过的城市(本地缓存)
List _historyList = [];
// 本地存储实例:用于操作shared_preferences
late SharedPreferences _prefs;
// 网络请求实例:用于请求天气接口
final Dio _dio = Dio();
// 加载状态:控制加载动画显示/隐藏
bool _isLoading = false;
// 生命周期方法:组件初始化时执行,加载本地缓存的查询历史
@override
void initState() {
super.initState();
// 初始化本地存储,加载历史记录
_initPrefs();
}
// 初始化本地存储,加载查询历史
Future _initPrefs() async {
_prefs = await SharedPreferences.getInstance();
// 从本地读取查询历史,若有数据则赋值给_historyList
List? history = _prefs.getStringList(‘weather_history’);
if (history != null && history.isNotEmpty) {
setState(() {
_historyList = history;
});
}
}
// 保存查询历史到本地(持久化存储,关闭APP不丢失)
Future _saveHistory(String city) async {
// 避免重复添加同一城市(去重)
if (!_historyList.contains(city)) {
setState(() {
_historyList.add(city);
});
// 将历史列表保存到本地
await _prefs.setStringList(‘weather_history’, _historyList);
}
}
// 删除单条查询历史
Future _deleteSingleHistory(int index) async {
setState(() {
_historyList.removeAt(index);
});
// 更新本地存储的历史列表
await _prefs.setStringList(‘weather_history’, _historyList);
Fluttertoast.showToast(msg: “已删除该查询记录”);
}
// 清空全部查询历史
Future _clearAllHistory() async {
setState(() {
_historyList.clear();
});
// 清空本地存储的历史列表
await _prefs.setStringList(‘weather_history’, _historyList);
Fluttertoast.showToast(msg: “已清空全部查询记录”);
}
// 核心方法:查询天气(调用第三方免费接口,无需申请密钥,新手友好)
Future _queryWeather(String city) async {
// 非空判断:若城市名称为空,提示用户
if (city.trim().isEmpty) {
Fluttertoast.showToast(msg: “请输入城市名称”);
return;
}
// 显示加载动画
setState(() {
_isLoading = true;
});
try {
// 免费天气接口(无需密钥,直接调用,适配鸿蒙6.0+网络请求)
String url = "https://v0.yiketianqi.com/api?unescape=1&version=v91&appid=43656176&appsecret=I42og6Lm&city=$city";
// 发送GET请求,获取天气数据
Response response = await _dio.get(url);
// 解析接口返回的JSON数据
Map<String, dynamic> data = response.data;
// 判断接口请求是否成功
if (data['code'] == 200) {
// 将JSON数据转为WeatherModel对象
WeatherModel weather = WeatherModel.fromJson({
'city': data['city'],
'temp': data['tem'],
'weather': data['wea'],
'updateTime': data['update_time'],
});
// 更新当前天气数据,刷新界面
setState(() {
_currentWeather = weather;
});
// 保存查询历史到本地
_saveHistory(city);
// 提示用户查询成功
Fluttertoast.showToast(msg: "查询成功!");
} else {
// 接口请求失败(如城市不存在)
Fluttertoast.showToast(msg: "查询失败,请输入正确的城市名称");
}
} catch (e) {
// 捕获异常(如网络异常、接口报错)
Fluttertoast.showToast(msg: "网络异常,请检查网络连接");
} finally {
// 无论请求成功/失败,都关闭加载动画
setState(() {
_isLoading = false;
});
}
}
// 点击历史记录,快速重新查询
void _queryHistoryWeather(String city) {
// 清空输入框,重新赋值当前城市
_cityController.text = city;
// 调用查询天气方法
_queryWeather(city);
}
// UI布局(适配鸿蒙6.0+屏幕尺寸和交互习惯)
@override
Widget build(BuildContext context) {
return Scaffold(
// 导航栏(适配鸿蒙6.0+导航栏样式,居中显示标题)
appBar: AppBar(
title: const Text(“Flutter鸿蒙天气查询”),
centerTitle: true,
backgroundColor: Colors.blue,
),
// 页面内容容器(垂直布局,适配鸿蒙不同屏幕尺寸)
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// 1. 城市输入框 + 查询按钮
Row(
children: [
// 城市输入框
Expanded(
child: TextField(
controller: _cityController,
decoration: const InputDecoration(
labelText: “请输入城市名称”,
border: OutlineInputBorder(),
hintText: “例如:北京、上海”,
contentPadding: EdgeInsets.symmetric(horizontal: 15, vertical: 12),
),
style: const TextStyle(fontSize: 16),
// 按下键盘回车,触发查询
onSubmitted: (value) => _queryWeather(value),
),
),
const SizedBox(width: 10),
// 查询按钮
ElevatedButton(
onPressed: () => _queryWeather(_cityController.text.trim()),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
backgroundColor: Colors.blue,
),
child: const Text(“查询”),
),
],
),
const SizedBox(height: 20),
// 2. 天气显示区域(查询到天气后显示,未查询时隐藏)
_currentWeather != null
? Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
// 城市名称
Text(
_currentWeather!.city,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 15),
// 实时温度
Text(
"${_currentWeather!.temp}℃",
style: const TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// 天气状态
Text(
_currentWeather!.weather,
style: const TextStyle(fontSize: 20, color: Colors.grey),
),
const SizedBox(height: 10),
// 更新时间
Text(
"更新时间:${_currentWeather!.updateTime}",
style: const TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
),
)
: const SizedBox(), // 未查询时,不显示任何内容
// 加载动画(查询过程中显示)
if (_isLoading)
const Padding(
padding: EdgeInsets.all(20.0),
child: CircularProgressIndicator(color: Colors.blue),
),
const SizedBox(height: 20),
// 3. 查询历史区域
const Text(
"查询历史",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// 历史记录列表(无历史时显示提示,有历史时显示列表)
_historyList.isEmpty
? const Center(
child: Text(
"暂无查询历史,快去查询天气吧~",
style: TextStyle(fontSize: 16, color: Colors.grey),
),
)
: Expanded(
child: ListView.builder(
itemCount: _historyList.length,
itemBuilder: (context, index) {
String city = _historyList[index];
return ListTile(
// 历史城市名称
title: Text(city),
// 点击历史记录,重新查询
onTap: () => _queryHistoryWeather(city),
// 右侧删除按钮,删除单条历史
trailing: IconButton(
icon: const Icon(Icons.delete, color: Colors.grey),
onPressed: () => _deleteSingleHistory(index),
),
);
},
),
),
// 清空历史按钮(有历史记录时显示)
if (_historyList.isNotEmpty)
TextButton(
onPressed: _clearAllHistory,
child: const Text(
"清空全部历史",
style: TextStyle(color: Colors.red),
),
),
],
),
),
);
}
}
本项目使用 Flutter + 3 个高频三方库,实现了可在 鸿蒙 6.0+(API20+) 运行的跨端天气查询应用,全程遵循新手友好原则,无复杂配置、无需申请接口密钥,代码带详细注释,复制即可运行。
核心亮点:
贴合日常使用场景,功能实用,可直接作为鸿蒙跨端开发入门案例。
完整覆盖 “网络请求、本地存储、UI 适配” 三大核心知识点,适合新手巩固 Flutter 和鸿蒙融合开发技能。
适配鸿蒙 6.0 + 系统的交互和渲染,无卡顿、闪退等兼容性问题,符合鸿蒙应用开发规范。
与之前的备忘录、计算器、图片预览、待办清单、记账本项目完全无重复,拓展你的 Flutter 鸿蒙实战案例库。
作为鸿蒙开发者,你可以基于本项目进一步拓展功能,如添加未来 7 天天气预报、空气质量显示、城市定位等,提升项目复杂度和实用性。
更多推荐

所有评论(0)