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

鸿蒙5.0项目开发——鸿蒙天气项目的实现(主页1)

【高心星出品】

文章目录

      • 页面效果:
      • 页面功能:
      • 页面执行流程:
      • 1. 页面初始化阶段
      • 2. 定位获取阶段
      • 3. 天气数据加载阶段

这个页面是整个天气应用的核心,集成了天气查询、定位、搜索等主要功能,提供了完整的天气信息服务。

页面效果:

在这里插入图片描述

页面功能:

1. 天气信息展示

  • 当前天气信息:

  • 城市名称

  • 温度

  • 天气状况

  • 湿度

  • 风速

  • PM2.5

  • 空气质量

  • 未来天气预报:

  • 显示未来3天的天气

  • 包含星期、天气类型、温度范围

2. 定位功能

  • 自动定位:

  • 请求定位权限

  • 获取当前位置

  • 根据位置获取城市信息

  • 显示当前位置天气

3. 搜索功能

  • 城市搜索:

  • 搜索框输入城市名

  • 实时搜索天气信息

  • 保存搜索历史

4. 搜索历史管理

  • 历史记录功能:

  • 显示搜索历史列表

  • 支持删除单条记录

  • 支持清空所有历史

  • 点击历史记录可快速查看天气

5. 界面交互

  • 左侧抽屉菜单:

  • 显示搜索历史

  • 支持滑动关闭

  • 编辑模式切换

  • 删除历史记录

6. 加载状态

  • 加载提示:

  • 显示加载动画

  • 错误提示对话框

  • 操作结果提示

7. 数据管理

  • 数据持久化:

  • 保存搜索历史

  • 缓存天气数据

  • 管理城市信息

8. 错误处理

  • 异常处理:

  • 网络错误提示

  • 定位失败处理

  • 数据加载失败处理

页面执行流程:

1. 页面初始化阶段

  1. 页面加载时触发 aboutToAppear 生命周期

  2. 首先检查定位权限

    • 如果有权限,直接开启定位

    • 如果没有权限,向用户请求权限

    • 用户同意后开启定位,拒绝则使用默认城市(南京市)

  /*** 组件即将出现时的生命周期函数* @description * 1. 首先请求定位权限* 2. 获取当前位置信息*/async aboutToAppear(): Promise<void> {// 请求定位权限await this.locationpermission()// 获取当前位置信息this.getlocation()}
 /*** 请求定位权限* @description * 1. 创建权限管理器实例* 2. 获取应用程序的accessTokenID* 3. 校验应用是否被授予定位权限* 4. 如果未授权,则请求用户授权* 5. 根据用户授权结果执行相应操作*/async locationpermission() {// 创建权限管理器实例let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();// 初始化权限状态为拒绝let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;// 获取应用程序的accessTokenIDlet tokenId: number = 0;let bundleInfo: bundleManager.BundleInfo =await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;tokenId = appInfo.accessTokenId;// 校验应用是否被授予定位权限grantStatus = await atManager.checkAccessToken(tokenId, 'ohos.permission.APPROXIMATELY_LOCATION');if (grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {// 如果未授权,请求用户授权atManager.requestPermissionsFromUser(this.context, ['ohos.permission.APPROXIMATELY_LOCATION']).then((data) => {let grantStatus: Array<number> = data.authResults;if (grantStatus[0] === 0) {// 用户同意授权,修改lcc值触发lc函数执行this.lcc = 2} else {// 用户拒绝授权,弹窗提示AlertDialog.show({message: '您已拒绝授权定位,无法体验当前位置天气的信息功能',title: '提示',confirm: {value: '确定', action: () => {}}})}}).catch((e: Error) => {// 授权过程发生错误console.error('gxxt 授权', e.message)})} else {// 已有权限,设置lcc=1this.lcc = 1}}

2. 定位获取阶段

  1. 检查系统定位是否开启

    • 如果已开启,直接获取位置

    • 如果未开启,请求用户开启定位

  2. 获取当前位置信息

  3. 根据位置信息获取城市名称

  4. 如果获取失败,使用默认城市

/*** 获取位置信息* @description 根据定位权限状态决定是否开启定位* - 如果lcc=1表示有定位权限,则开启定位* - 否则直接加载默认城市天气*/getlocation() {if (this.lcc == 1) {// 开启定位this.openlocation()} else {this.loadweather(this.cityName, false)}}/*** 开启定位功能* @description 检查并请求开启系统定位功能* 1. 首先检查定位功能是否已开启* 2. 如果未开启,则请求用户开启* 3. 开启成功后调用locationreq()获取位置* 4. 开启失败则提示用户* @throws 可能抛出定位相关错误*/openlocation() {try {// 检查定位功能是否开启let enable = geoLocationManager.isLocationEnabled()if (!enable) {// 创建权限管理器let atmanager = abilityAccessCtrl.createAtManager()// 请求开启定位功能atmanager.requestGlobalSwitch(this.context, abilityAccessCtrl.SwitchType.LOCATION).then((value) => {if (value) { // 开启定位成功this.locationreq()} else { // 开启定位失败AlertDialog.show({message: '定位开启失败', title: '提示', confirm: {value: '确定',action: () => {}}})}})} else {// 定位已开启,直接获取位置this.locationreq()}} catch (e) {console.error('gxxt location ', JSON.stringify(e))}}/*** 获取定位城市信息* @description 通过系统定位服务获取当前位置并解析城市名称* 1. 首先显示加载动画弹窗* 2. 配置定位请求参数,优先考虑定位速度,超时时间10秒* 3. 调用getCurrentLocation获取经纬度坐标* 4. 根据经纬度反向解析获取城市名称* 5. 成功获取城市名称后加载该城市天气* 6. 失败则加载默认城市天气*/locationreq() {// 显示加载动画弹窗this.opendialog()// 配置定位请求参数let request: geoLocationManager.SingleLocationRequest = {'locatingPriority': geoLocationManager.LocatingPriority.PRIORITY_LOCATING_SPEED,'locatingTimeoutMs': 10000}// 获取当前位置geoLocationManager.getCurrentLocation(request).then((result) => {// 配置反向地理编码请求参数let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest ={ "latitude": result.latitude, "longitude": result.longitude, "maxItems": 1 };// 根据经纬度获取地址信息geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest, (err, data) => {if (err) {// 获取城市名称失败console.log('gxxt getAddressesFromLocation err: ' + JSON.stringify(err));promptAction.showToast({ message: '获取城市名称失败,请连接网络!' })// 加载默认城市天气this.loadweather(this.cityName, false)} else {// 获取城市名称成功,加载该城市天气this.loadweather(data[0].locality as string, false)}});}).catch((error: BusinessError) => {// 定位失败处理console.error('gxxt , getCurrentLocation: error=' + JSON.stringify(error));promptAction.showToast({ message: '无法获取地理位置' })// 加载默认城市天气this.loadweather(this.cityName, false)});}

3. 天气数据加载阶段

  1. 根据城市名称查询城市编码

  2. 使用城市编码获取天气数据

  3. 更新界面显示:

    • 当前天气信息(温度、天气状况等)

    • 未来三天天气预报

    • 空气质量等信息

  4. 如果是搜索操作,保存搜索历史

/*** 加载天气信息* @param cityname 城市名称* @param issearch 是否是搜索请求* @description 根据城市名称加载天气信息* 1. 首先根据城市名称查询城市编码* 2. 使用城市编码获取天气数据* 3. 如果不是搜索请求则关闭加载弹窗* 4. 如果是搜索请求则保存搜索历史* 5. 更新页面上的天气信息显示* 6. 包括:城市名、温度、天气描述、湿度、风速、PM2.5、空气质量* 7. 更新未来3天的天气预报信息*/private async loadweather(cityname: string, issearch: boolean) {let ad = new adcodedao(this.context)try {// 查询城市编码let code = await ad.querybyname(cityname)// 获取天气数据let weather = await getweather(code)if (!issearch) {// 非搜索请求,关闭加载弹窗this.closedialog()} else {// 搜索请求,保存搜索历史let sd = new searchdao(this.context)sd.insert({ keyword: cityname })}// 更新城市基本信息this.cityName = weather.cityInfo.citythis.temperature = weather.data.wenduthis.weatherDesc = weather.data.forecast[0].typethis.humidity = weather.data.shiduthis.windSpeed = weather.data.forecast[0].flthis.pm25 = weather.data.pm25 + ''this.quality = weather.data.quality// 更新未来3天天气预报this.day1week = weather.data.forecast[1].weekthis.day1type = weather.data.forecast[1].typethis.day1wendu = getwendu(weather.data.forecast[1].low, weather.data.forecast[1].high)this.day2week = weather.data.forecast[2].weekthis.day2type = weather.data.forecast[2].typethis.day2wendu = getwendu(weather.data.forecast[2].low, weather.data.forecast[2].high)this.day3week = weather.data.forecast[3].weekthis.day3type = weather.data.forecast[3].typethis.day3wendu = getwendu(weather.data.forecast[3].low, weather.data.forecast[3].high)} catch (e) {// 显示错误提示对话框AlertDialog.show({message: '该地区天气信息暂无法获取!', title: '提示', confirm: {value: '确定', action: () => {}}})}}

根据城市名称查询城市编码:

  /*** 根据城市名称查询城市编码* @param name 城市名称* @returns 城市编码* @description * 1. 根据城市名称模糊查询数据库* 2. 只查询code字段* 3. 如果查询到结果则返回城市编码* 4. 如果查询失败则返回空字符串*/async querybyname(name: string) {let code: string = ''try {let rdb = await getrdb(this.context)let predicates = new relationalStore.RdbPredicates(TABLENAME)predicates.like('name', '%' + filter(name) + '%')let rs = await rdb.query(predicates, ['code'])if (rs.goToNextRow()) {code = rs.getString(rs.getColumnIndex('code'))}} catch (e) {console.error('gxxt adcodedao 查询失败: ', JSON.stringify(e))}return code}

使用城市编码获取天气数据

/*** 天气API的基础URL*/
export const BASEURL = 'http://t.weather.itboy.net/api/weather/city/'/*** 获取城市天气信息* @param citycode 城市编码* @returns Promise<weathermodel> 返回天气数据模型* @description * 1. 根据城市编码拼接完整的API URL* 2. 创建HTTP请求实例* 3. 配置请求头为JSON格式* 4. 发送GET请求获取天气数据* 5. 解析响应数据为weathermodel类型* 6. 如果状态码为200则返回数据* 7. 否则抛出错误* 8. 最后销毁HTTP请求实例*/
export function getweather(citycode: string) {let url = BASEURL + citycodelet req = http.createHttp()let opt: http.HttpRequestOptions = {header: {'Content-Type': 'application/json;charset=UTF-8'}}return new Promise<weathermodel>((resove, reject) => {req.request(url, opt).then((res) => {let data =JSON.parse( res.result as string) as weathermodelif(data.status==200) {resove(data)}else{reject('不在范围之内')}}).catch((e: Error) => {reject(e)}).finally(() => {req.destroy()})})}

相关文章:

鸿蒙5.0项目开发——鸿蒙天气项目的实现(主页1)

【高心星出品】 文章目录 页面效果&#xff1a;页面功能&#xff1a;页面执行流程&#xff1a;1. 页面初始化阶段2. 定位获取阶段3. 天气数据加载阶段 这个页面是整个天气应用的核心&#xff0c;集成了天气查询、定位、搜索等主要功能&#xff0c;提供了完整的天气信息服务。 …...

python项目参考文献

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

【ESP32】ESP-IDF开发 | 低功耗蓝牙开发 | GATT规范和ATT属性协议 + 电池电量服务例程

1. 简介 低功耗蓝牙中最为核心的部分当属 GATT&#xff08;Generic Attribute Profile&#xff09;&#xff0c;全称通用属性配置文件。而 GATT 又是建立在 ATT 协议&#xff08;属性协议&#xff09;的基础之上&#xff0c;为 ATT 协议传输和存储的数据建立了通用操作和框架。…...

2025 年九江市第二十三届中职学校技能大赛 (网络安全)赛项竞赛样题

2025 年九江市第二十三届中职学校技能大赛 &#xff08;网络安全&#xff09;赛项竞赛样题 &#xff08;二&#xff09;A 模块基础设施设置/安全加固&#xff08;200 分&#xff09;A-1 任务一登录安全加固&#xff08;Windows,Linux&#xff09;A-2 任务二 Nginx 安全策略&…...

【记录】Windows|竖屏怎么调整分辨率使横竖双屏互动鼠标丝滑

本文版本&#xff1a;Windows11&#xff0c;记录一下&#xff0c;我最后调整的比较舒适的分辨率是800*1280。 文章目录 第一步 回到桌面第二步 右键桌面第三步 设置横屏为主显示器第四步 调整分辨率使之符合你的需求第五步 勾选轻松在显示器之间移动光标第六步 拖动屏幕符合物理…...

开源项目实战学习之YOLO11:12.2 ultralytics-models-sam-decoders.py源码分析

👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-decoders.pyblocks.py: 定义模型中的各…...

数据结构*优先级队列(堆)

什么是优先级队列(堆) 优先级队列一般通过堆&#xff08;Heap&#xff09;这种数据结构来实现&#xff0c;堆是一种特殊的完全二叉树&#xff0c;其每个节点都满足堆的性质。如下图所示就是一个堆&#xff1a; 堆的存储方式 由于堆是一棵完全二叉树&#xff0c;所以也满足二…...

汽车Wafer连接器:工业设备神经网络的隐形革命者

汽车Wafer连接器正在突破传统车载场景的边界&#xff0c;以毫米级精密结构重构工业设备的连接范式。这款厚度不足3毫米的超薄连接器&#xff0c;在新能源电池模组中承载200A持续电流的同时&#xff0c;仍能保持85℃温升的稳定表现&#xff0c;其每平方厘米高达120针的触点密度&…...

微信小程序:封装表格组件并引用

一、效果 封装表格组件,在父页面中展示表格组件并显示数据 二、表格组件 1、创建页面 创建一个components文件夹,专门用于存储组件的文件夹 创建Table表格组件 2、视图层 (1)表头数据 这里会从父组件中传递表头数据,这里为columns,后续会讲解数据由来 循环表头数组,…...

湖北理元理律师事务所:债务优化中的双维支持实践解析

在债务压力与生活质量失衡的社会议题下&#xff0c;法律服务机构的功能边界正在从单一的法律咨询向复合型支持延伸。湖北理元理律师事务所通过“法律心理”双维服务模式&#xff0c;探索债务优化与生活保障的平衡路径&#xff0c;其方法论或为行业提供实践参考。 法律框架&…...

uniapp在APP上如何使用websocket--详解

UniApp 在 APP 端如何使用 WebSocket以及常见问题 一、WebSocket 基础概念 WebSocket 是一种在单个TCP连接上进行全双工通信的协议&#xff0c;适用于实时数据传输场景&#xff08;如聊天室、实时游戏、股票行情等&#xff09;。 与传统HTTP对比 特性WebSocketHTTP连接方式…...

计网| 网际控制报文协议(ICMP)

目录 网际控制报文协议&#xff08;ICMP&#xff09; 一、ICMP 基础特性 二、ICMP 报文分类及作用 差错报告报文 询问报文 网际控制报文协议&#xff08;ICMP&#xff09; ICMP&#xff08;Internet Control Message Protocol&#xff0c;网际控制报文协议&#xff09;是 …...

Conda 完全指南:从环境管理到工具集成

Conda 完全指南&#xff1a;从环境管理到工具集成 在数据科学、机器学习和 Python 开发领域&#xff0c;环境管理一直是令人头疼的问题。不同项目依赖的库版本冲突、Python 解释器版本不兼容等问题频繁出现&#xff0c;而 Conda 的出现彻底解决了这些痛点。作为目前最流行的跨…...

安卓中0dp和match_parent区别

安卓中的 0dp 和 match_parent 的区别&#xff1f; 第一章 前言 有段时间&#xff0c;看到同事在编写代码的时候&#xff0c;写到的是 0dp 有时候自己写代码的时候&#xff0c;编写的是 match_parent 发现有时候效果很类似。 后来通过一个需求案例&#xff0c;才发现两者有着…...

蓝桥杯-不完整的算式

问题描述 小蓝在黑板上写了一个形如 AopBCAopBC 的算式&#xff0c;其中 AA、BB、CC 都是非负整数&#xff0c;opop 是 、-、*、/、-、*、/&#xff08;整除&#xff09;四种运算之一。不过 AA、opop、BB、CC 这四部分有一部分被不小心的同学擦掉了。 给出这个不完整的算式&a…...

信贷风控笔记4——贷前策略之额度、定价(面试准备12)

1.贷前模型的策略应用 分类&#xff1a;审批准入&#xff08;对头尾部区分度要求高&#xff09;&#xff1a;单一规则&#xff08;找lift>3的分数做规则&#xff09;&#xff1b;二维交叉&#xff1b;拒绝回捞 额度定价&#xff08;对排序性要求高&#xff09;&am…...

A级、B级弱电机房数据中心建设运营汇报方案

该方案围绕A 级、B 级弱电机房数据中心建设与运营展开,依据《数据中心设计规范》等标准,施工范围涵盖 10 类机房及配套设施,采用专业化施工团队与物资调配体系,强调标签规范、线缆隐藏等细节管理。运营阶段建立三方协同运维模式,针对三级故障制定30 分钟至 1 小时响应机制…...

Linux中的域名解析服务器

一、DNS&#xff08;域名系统&#xff09;详解 1. 核心功能与特点 特性说明核心作用将域名&#xff08;如 www.example.com&#xff09;转换为 IP 地址&#xff08;如 192.168.1.1&#xff09;&#xff0c;实现人类可读地址与机器可读地址的映射。端口与协议- 默认端口&#…...

如何优化Java中十进制字符串转十六进制的性能

在 Java 中优化十进制字符串转十六进制的性能&#xff0c;可以从减少对象创建、避免正则表达式、使用高效数据结构等方面入手。以下是具体的优化方案&#xff1a; 1. 避免字符串分割&#xff0c;直接遍历字符数组 原始方法&#xff08;频繁创建子字符串&#xff09;&#xff1…...

CycleISP: Real Image Restoration via Improved Data Synthesis通过改进数据合成实现真实图像恢复

摘要 大规模数据集的可用性极大释放了深度卷积神经网络(CNN)的潜力。然而,针对单图像去噪问题,获取真实数据集成本高昂且流程繁琐。因此,图像去噪算法主要基于合成数据开发与评估,这些数据通常通过广泛假设的加性高斯白噪声(AWGN)生成。尽管CNN在合成数据集上表现优异…...

Day28 Python打卡训练营

知识点回顾&#xff1a; 1. 类的定义 2. pass占位语句 3. 类的初始化方法 4. 类的普通方法 5. 类的继承&#xff1a;属性的继承、方法的继承 作业 题目1&#xff1a;定义圆&#xff08;Circle&#xff09;类 要求&#xff1a; 1. 包含属性&#xff1a;半径 radius。 2. …...

【OpenCV】基本数据类型及常见图像模式

是什么&#xff1f;能做什么&#xff1f;解决什么问题&#xff1f;为什么用它&#xff1f; OpenCV:是一个基于开源发行的跨平台计算机视觉库&#xff0c;实现 一、应用场景&#xff1a; 目标识别&#xff1a;人脸、车辆、车牌...自动驾驶医学影像分析视频内容理解与分析&…...

Linux之Nginx安装及配置原理篇(一)

Nginx安装及配置 前情回顾 首先针对Nginx进程模型&#xff0c;我们回顾一下它的原理机制&#xff0c;我们知道它是通过Master通过fork分发任务节点给予work节点&#xff0c;然后work节点触发了event事件&#xff0c;之后通过一个access_muttex互斥锁&#xff0c;来单线程调用我…...

【Linux网络】NAT和代理服务

NAT 之前我们讨论了&#xff0c;IPv4协议中&#xff0c;IP地址数量不充足的问题。 原始报文途径路由器WAN口时&#xff0c;对报文中的源IP进行替换的过程&#xff0c;叫做NAT。 NAT技术当前解决IP地址不够用的主要手段&#xff0c;是路由器的一个重要功能&#xff1a; NAT能…...

中药药效成分群的合成生物学研究进展-文献精读130

Advances in synthetic biology for producing potent pharmaceutical ingredients of traditional Chinese medicine 中药药效成分群的合成生物学研究进展 摘要 中药是中华民族的文化瑰宝&#xff0c;也是我国在新药创制领域的重要驱动力。许多中药材来源于稀缺物种&#xf…...

【消息队列】RabbitMQ基本认识

目录 一、基本概念 1. 生产者&#xff08;Producer&#xff09; 2. 消费者&#xff08;Consumer&#xff09; 3. 队列&#xff08;Queue&#xff09; 4. 交换器&#xff08;Exchange&#xff09; 5. 绑定&#xff08;Binding&#xff09; 6. 路由键&#xff08;Routing …...

OCCT知识笔记之OCAF框架详解

OCAF框架在OCCT项目中的构建与使用指南 Open CASCADE Application Framework (OCAF)是Open CASCADE Technology (OCCT)中用于管理CAD数据的核心框架&#xff0c;它提供了一种结构化方式来组织和管理复杂的CAD数据&#xff0c;如装配体、形状、属性(颜色、材料)和元数据等。本文…...

蓝桥杯 16. 外卖店优先级

外卖店优先级 原题目链接 题目描述 “饱了么” 外卖系统中维护着 N 家外卖店&#xff0c;编号 1 ∼ N。每家外卖店都有一个优先级&#xff0c;初始时&#xff08;0 时刻&#xff09;优先级都为 0。 每经过 1 个时间单位&#xff1a; 如果外卖店没有订单&#xff0c;则优先…...

1T 服务器租用价格解析

服务器作为数据存储与处理的核心设备&#xff0c;对于企业和个人开发者而言至关重要。当涉及到租用 1T 服务器时&#xff0c;价格是大家很为关注的要点。然而&#xff0c;1T 服务器租用一个月的费用并非固定不变&#xff0c;而是受到诸多因素的综合影响。​ 影响 1T 服务器租用…...

【JavaWeb】Maven(下)

1 依赖管理 1.1 依赖配置 1.1.1 基本配置 依赖&#xff1a;指当前项目运行所需要的jar包。 一个项目中可以引入多个依赖&#xff1a; 例如&#xff1a;在当前工程中&#xff0c;我们需要用到logback来记录日志&#xff0c;此时就可以在maven工程的pom.xml文件中&#xff0c;引…...