鸿蒙OS开发:【一次开发,多端部署】(一多天气)项目

一多天气

介绍

本示例展示一个天气应用界面,包括首页、城市管理、添加城市、更新时间弹窗,体现一次开发,多端部署的能力。

1.本示例参考一次开发,多端部署的指导,主要使用响应式布局的栅格断点系统实现在不同尺寸窗口界面上不同的显示效果。

2.使用[SideBarContainer]实现侧边栏功能。

3.使用[栅格容器组件]实现界面内容的分割和展示。

4.使用Canvas和CanvasRenderingContext2D完成空气质量和日出月落图的曲线绘制。

开发前请熟悉鸿蒙开发指导文档gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。

效果预览

image.png

使用说明:

1.启动应用后,首页展示已添加城市的天气信息,默认展示2个城市,左右滑动可以切换城市,在LG设备上,默认显示侧边栏,侧边栏显示时,右侧内容区占2/3,侧边栏隐藏时,内容区自动铺满界面。

2.在支持窗口自由拖拽的设备上,拖拽窗口大小,可以分别实现拖动到最大窗口侧边栏显示(点击侧边栏控制按钮可以隐藏和显示侧边栏),拖动窗口缩小到MD大小时侧边栏和侧边栏控制按钮隐藏。

3.在支持窗口自由拖拽的设备上,拖拽窗口大小,天气内容区跟随窗口大小会自动换行显示。

4.点击右上角菜单按钮,在菜单中点击更新时间,弹出更新时间弹窗,没有功能,此处只做展示,在平板设备上显示2列,在小屏设备上显示一列。

5.点击右上角菜单按钮,在菜单中点击管理城市,进入管理城市界面,展示已添加的城市,在平板设备上显示2列,在小屏设备上显示一列。

6.点击管理城市界面的添加城市,进入添加城市界面,已添加的城市不可点击,未添加的城市点击可以添加并返回管理城市界面显示。

工程目录

/code/SuperFeature/MultiDeviceAppDev/Weather/product/default
└─src├─main│  ││  ├─ets│  │  ├─Application│  │  │      MyAbilityStage.ts          //自定义ability│  │  ││  │  ├─common                          //公共资源库│  │  ├─feature│  │  │      AirQualityFeature.ts       //空气绘画│  │  │      SunCanvasFeature.ts        //晴天绘画│  │  ││  │  ├─MainAbility│  │  │      MainAbility.ts             //主窗口│  │  ││  │  └─pages│  │      │  AddCity.ets                //添加城市│  │      │  CityList.ets               //城市列表│  │      │  Home.ets                   //入口│  │      ││  │      └─home│  │              AirQuality.ets         //空气质量│  │              HomeContent.ets        //主页面│  │              HoursWeather.ets       //每小时天气组件│  │              IndexEnd.ets           //首页尾 │  │              IndexHeader.ets        //首页头│  │              IndexTitleBar.ets      //首页标题│  │              LifeIndex.ets          //生活建议│  │              MultidayWeather.ets    //天气组件│  │              SideContent.ets        //侧边栏│  │              SunCanvas.ets          //晴天样式│  │              UpdateTimeDialog.ets   //时间更新弹窗│  ││  └─resources                           //资源包                                             

具体实现

1、home.ets中引入SideContent()和homeContent()。
2、定义showSideBar来判断是否展示侧边栏,定义mediaquery.MediaQueryListener媒体监听器smListener、mdListener、lgListener。
3、在aboutToAppear调用mediaquery对界面进行监听,[源码参考]。

/** Copyright (c) 2022-2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import mediaquery from '@ohos.mediaquery';import HomeContent from './home/HomeContent';import IndexTitleBar from './home/IndexTitleBar';import SideContent from './home/SideContent';import { CityListData, Style, getBg, getCityListWeatherData, Logger } from '@ohos/common';const TAG: string = 'Home';@Entry@Componentstruct Home {@StorageLink('isRefresh') @Watch('refreshChange') isRefresh: boolean = false;@StorageLink('swiperIndex') swiperIndex: number = 0;@State curBp: string = 'md';@State cityListWeatherData: CityListData[] = getCityListWeatherData();@State popupState: boolean = false;@State showSideBar: boolean = false;private smListener: mediaquery.MediaQueryListener;private mdListener: mediaquery.MediaQueryListener;private lgListener: mediaquery.MediaQueryListener;build() {SideBarContainer(SideBarContainerType.Embed) {SideContent({ showSideBar: $showSideBar }).height('100%')Column() {IndexTitleBar({ showSideBar: $showSideBar }).height(56)Swiper() {ForEach(this.cityListWeatherData, (item, index) => {HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })}, item => item.city)}.id('swiper').padding({ left: Style.NORMAL_PADDING, right: Style.NORMAL_PADDING }).indicatorStyle({selectedColor: Color.White}).onChange(index => {this.swiperIndex = index;AppStorage.SetOrCreate('swiperIndex', this.swiperIndex);}).indicator(this.curBp !== 'lg').index(this.swiperIndex).loop(false).width('100%').layoutWeight(1)}.height('100%')}.height('100%').sideBarWidth('33.3%').minSideBarWidth('33.3%').maxSideBarWidth('33.3%').showControlButton(false).showSideBar(this.showSideBar).backgroundImageSize(ImageSize.Cover).backgroundImage(getBg(this.cityListWeatherData[this.swiperIndex].header.weatherType))}aboutToAppear() {this.smListener = mediaquery.matchMediaSync('(320vp<width<=600vp)');this.smListener.on("change", this.isBreakpointSM);this.mdListener = mediaquery.matchMediaSync('(600vp<width<=840vp)');this.mdListener.on("change", this.isBreakpointMD);this.lgListener = mediaquery.matchMediaSync('(840vp<width)');this.lgListener.on("change", this.isBreakpointLG);}aboutToDisappear() {this.smListener.off("change", this.isBreakpointSM);this.mdListener.off("change", this.isBreakpointMD);this.lgListener.off("change", this.isBreakpointLG);}isBreakpointSM = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'sm';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointMD = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'md';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointLG = (mediaQueryResult) => {if (mediaQueryResult.matches) {if (this.curBp !== 'lg') {this.showSideBar = true;}this.curBp = 'lg';AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}refreshChange() {Logger.info(TAG, `refreshChange}`);if (this.isRefresh) {this.cityListWeatherData = getCityListWeatherData();AppStorage.SetOrCreate('isRefresh', false);}Logger.info(TAG, `refreshChange, this.cityListWeatherData.length = ${this.cityListWeatherData.length}`);}}`HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

搜狗高速浏览器截图20240326151450.png

4、监听到当前屏幕大小,调用this.isBreakpoint断点,对curBp、showSideBar进行赋值,[源码参考]。

/** Copyright (c) 2022-2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import mediaquery from '@ohos.mediaquery';import HomeContent from './home/HomeContent';import IndexTitleBar from './home/IndexTitleBar';import SideContent from './home/SideContent';import { CityListData, Style, getBg, getCityListWeatherData, Logger } from '@ohos/common';const TAG: string = 'Home';@Entry@Componentstruct Home {@StorageLink('isRefresh') @Watch('refreshChange') isRefresh: boolean = false;@StorageLink('swiperIndex') swiperIndex: number = 0;@State curBp: string = 'md';@State cityListWeatherData: CityListData[] = getCityListWeatherData();@State popupState: boolean = false;@State showSideBar: boolean = false;private smListener: mediaquery.MediaQueryListener;private mdListener: mediaquery.MediaQueryListener;private lgListener: mediaquery.MediaQueryListener;build() {SideBarContainer(SideBarContainerType.Embed) {SideContent({ showSideBar: $showSideBar }).height('100%')Column() {IndexTitleBar({ showSideBar: $showSideBar }).height(56)Swiper() {ForEach(this.cityListWeatherData, (item, index) => {HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })}, item => item.city)}.id('swiper').padding({ left: Style.NORMAL_PADDING, right: Style.NORMAL_PADDING }).indicatorStyle({selectedColor: Color.White}).onChange(index => {this.swiperIndex = index;AppStorage.SetOrCreate('swiperIndex', this.swiperIndex);}).indicator(this.curBp !== 'lg').index(this.swiperIndex).loop(false).width('100%').layoutWeight(1)}.height('100%')}.height('100%').sideBarWidth('33.3%').minSideBarWidth('33.3%').maxSideBarWidth('33.3%').showControlButton(false).showSideBar(this.showSideBar).backgroundImageSize(ImageSize.Cover).backgroundImage(getBg(this.cityListWeatherData[this.swiperIndex].header.weatherType))}aboutToAppear() {this.smListener = mediaquery.matchMediaSync('(320vp<width<=600vp)');this.smListener.on("change", this.isBreakpointSM);this.mdListener = mediaquery.matchMediaSync('(600vp<width<=840vp)');this.mdListener.on("change", this.isBreakpointMD);this.lgListener = mediaquery.matchMediaSync('(840vp<width)');this.lgListener.on("change", this.isBreakpointLG);}aboutToDisappear() {this.smListener.off("change", this.isBreakpointSM);this.mdListener.off("change", this.isBreakpointMD);this.lgListener.off("change", this.isBreakpointLG);}isBreakpointSM = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'sm';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointMD = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'md';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointLG = (mediaQueryResult) => {if (mediaQueryResult.matches) {if (this.curBp !== 'lg') {this.showSideBar = true;}this.curBp = 'lg';AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}refreshChange() {Logger.info(TAG, `refreshChange}`);if (this.isRefresh) {this.cityListWeatherData = getCityListWeatherData();AppStorage.SetOrCreate('isRefresh', false);}Logger.info(TAG, `refreshChange, this.cityListWeatherData.length = ${this.cityListWeatherData.length}`);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/18237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt 学习笔记】Qt窗口 | 工具栏 | QToolBar的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | 工具栏 | QToolBar的使用及说明 文章编号&#xff1a;Qt 学习…

opencv文档py_contours示例整理

文章目录 目录说明contours_begin目标什么是轮廓?如何画等高线?轮廓逼近法contour_features目标1.Moments 时刻2. Contour Area 轮廓面积3. Contour Perimeter 轮廓周长4. Contour Approximation 轮廓近似5. Convex Hull 凸包6. Checking Convexity 检查凸性7. Bounding Rect…

嵌入式进阶——RTC时钟

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 RTC时钟原理图PCF8563寄存器控制与状态寄存器 设备地址I2C环境初始化RTC寄存器数据读取RTC寄存器数据写入RTC闹钟设置RTC定时器设置…

2024.5.28晚训题解

提前预告&#xff0c;市赛初中组会考算法题&#xff0c;应该会有两道模板题 比如DFS BFS 二分 简单动态规划&#xff0c;虽然我们没学多久&#xff0c;但是模板题你还是要会写的 A题 编辑距离 动态规划 注意多组输入 #include<iostream> using namespace std; int dp[1…

9、C#【进阶】特性

特性 文章目录 1、特性概念2、自定义特性 Attribute3、特性的使用4、限制自定义特性的使用范围5、系统自带特性1、过时特性2、调用者信息特性3、条件编译特性4、外部dll包函数特性 1、特性概念 特性是一种允许我们向程序的程序集添加元数据的语言结构 它是用于保存程序机构信息…

【机器学习300问】103、简单的经典卷积神经网络结构设计成什么样?以LeNet-5为例说明。

一个简单的经典CNN网络结构由&#xff1a;输入层、卷积层、池化层、全连接层和输出层&#xff0c;这五种神经网络层结构组成。它最最经典的实例是LeNet-5&#xff0c;它最早被设计用于手写数字识别任务&#xff0c;包含两个卷积层、两个池化层、几个全连接层&#xff0c;以及最…

ansible批量漏洞升级openssh版本

1、ansible宿主机准备好环境&#xff0c;并写好hosts文件 [rootoxidized ansible]# cat hosts [all] 10.10.200.33 10.10.200.34 10.10.200.35跑playbook之前记得提前发送秘钥 ssh-copy-id 10.10.200.33/34/352、下载好安装包&#xff0c;然后编写yml [rootoxidized ansible]…

【实用的 IDEA 配置和操作技巧总结】

前置知识 IDEA的设置快捷键为ctrlalts键&#xff0c;后文介绍IDEA常见的配置就不再赘述这一点了。 基础配置 取消默认打开上次项目 日常开发都会打开不同的项目&#xff0c;初次安装IDEA之后&#xff0c;每次打开IDEA都会开启上一次启动的项目&#xff0c;所以我们需要进入设…

0基础学习Mybatis系列数据库操作框架——Mysql的Geometry数据处理之WKB方案

大纲 序列化反序列化完整TypeHandlerSQL XML完整XML Mapper测试代码代码 在《0基础学习Mybatis系列数据库操作框架——Mysql的Geometry数据处理之WKT方案》中&#xff0c;我们介绍WTK方案的优点&#xff0c;也感受到它的繁琐和缺陷。比如&#xff1a; 需要借助ST_GeomFromText…

350种类型、10W+量级的API,企业应该怎么管?

忽如一夜春风来&#xff0c;万物皆可API。 在互联网时代&#xff0c;API无处不在&#xff1a;企业对外开放的数据、服务和业务能力&#xff0c;以API的形式提供给合作方&#xff1b;企业内部应用与应用、App与App之间的通信&#xff0c;通过API进行&#xff1b;甚至应用内部的…

php 连接sqlserver步骤

1.首先要确定使用的是sqlserver的哪个版本&#xff0c;比如sqlserver2012 2.确定服务器是64位还是32位的 3.确认一下使用php的哪个版本&#xff0c;比如php7.1 SQL Server 的 Microsoft PHP 驱动程序 Microsoft Drivers for PHP 支持矩阵 - PHP drivers for SQL Server | Mi…

怎么做好客户信息管理?

根据Forrester的调查表示&#xff0c;客户满意度的影响可能会使某些行业的收入每年增加高达 10 亿美元。而提升客户满意度的关键环节便是做好客户信息管理。但企业在进行客户信息管理中往往会遇到以下问题&#xff1a; 客户信息乱&#xff1a;客户信息存在各个 Excel表格、个人…

PMP报考条件怎么查询?如何判定自己是否符合条件?

PMP报考条件在PMI官网上就可以查询&#xff0c;PMP报考条件只需要符合项目管理培训经历和项目管理经验两个方面的要求即可&#xff0c;大家可以对照下方的规定判断自己是否符合PMP报名条件 PMP报考条件 以下是PMI&#xff08;中国&#xff09;官网对于PMP报名条件的规定&…

ubuntu strace命令

strace 是 Linux 系统中的一个调试工具&#xff0c;用于跟踪并记录系统调用&#xff08;system calls&#xff09;和信号&#xff08;signals&#xff09;。在 Ubuntu 中&#xff0c;strace 命令可以帮助开发者和系统管理员了解一个程序在运行时如何与操作系统内核进行交互&…

vue+antd实践:在输入框光标处插入内容

今天来看一个很简单的需求。 需求描述&#xff1a;在输入框光标处&#xff0c;插入指定的内容。 效果如下&#xff1a; 实现思路&#xff1a;刚开始还在想怎么获取光标的位置&#xff0c;但是发现所做的项目是基于vue3antd组件&#xff0c;那么不简单了嘛&#xff0c;只要调…

配置物联网平台 保姆级教程

一、云平台配置&#xff08;我们这里使用阿里云&#xff09; 1、注册和登录 &#xff08;1&#xff09;找到云平台官网&#xff0c;点击右上角的注册登录&#xff0c;完成之后&#xff0c;进行实名认证&#xff0c;任选一种认证方式。 ​​​​​​​ 2、实例的开通和创建 …

Scala环境的搭建

要搭建Scala&#xff0c;我们必须先下载java&#xff0c;由于我的电脑已经搭建好了环境&#xff0c;因此我这里用截图来教大家搭建环境。 可以从网上搜索安装包对其进行安装 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE 不建议下载最新版的&#xff0c;大家下载的版本可以下…

本杀小程序开发实战手册:从构思到上线

一、引言 随着移动互联网的快速发展&#xff0c;剧本杀作为一种新兴的娱乐方式&#xff0c;受到了越来越多年轻人的喜爱。为了满足市场需求&#xff0c;开发一款剧本杀小程序成为了许多创业者和开发者的选择。本文将从构思、设计、开发到上线等方面&#xff0c;为您详细解析剧…

第52期|GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

万界星空科技定制化MES系统帮助实现数字化生产

由于不同企业的生产流程、需求和目标各异&#xff0c;MES管理系统的个性化和定制化需求也不同。有些企业需要将MES管理系统与ERP等其他管理系统进行集成&#xff0c;以实现全面的信息共享和协同工作。有些企业需要将MES管理系统与SCADA等控制系统进行集成&#xff0c;以实现实时…