【中工开发者】——气候查询,鸿蒙OS
引言伴随智能手机的大规模普及,气候查询已然成为人们一样平常生存里不可或缺的关键构成部分。而鸿蒙操作体系(HarmonyOS)作为华为精心打造并推出的新一代智能终端操作体系,凭借其独特的技术架构与创新特性,为广大开发者们开启了一扇全新的开发大门,带来前所未有的开发体验。本文将会全方位、细致入微地先容基于鸿蒙 OS 开发一款气候查询应用的详细步骤与方法,其内容将完整覆盖从与数据接口进行对接获取景象信息,到实现都会信息管理中都会删除功能的一整套流畅流程,旨在为开发者们提供全面且极具价值的开发指引与参考范例
1. 数据接口获取
在开发气候查询应用之前,我们需要一个可靠的气候数据接口。这里我们可以选择公开的气候API,如高德地图、和风气候等。以高德地图为例,我们需要注册账号并获取一个API密钥(API Key),用于后续的数据请求。
1.1 获取API Key
访问OpenWeatherMap官网气候查询-基础 API 文档-开发指南-Web服务 API | 高德地图API气候查询-基础 API 文档-开发指南-Web服务 API | 高德地图API气候查询-基础 API 文档-开发指南-Web服务 API | 高德地图APIOpenWeatherMap官网,注册账号并订阅相应的服务,获取API Key。
https://i-blog.csdnimg.cn/direct/12d9f46f3a1f423d88d707790d41109a.png
2. 对象创建
在鸿蒙OS中,我们需要创建几个关键的对象来管理气候数据和用户界面。
2.1 气候数据模型
创建一个Casts类来存储气候数据,包罗白天 温度、夜晚温度、湿度、风向、等数据信息。
export class casts{
date:string=''
dayweather:string=''
nightweather:string=''
daytemp:number=0
nighttemp:number=0
daywind:string=''
daypower:string=''
daytemp_float:number=0
nighttemp_float:number=0
} 2.2 都会管理类
创建一个forecasts类来存储都会名称,代码,气候信息:
export class forecasts{
city:string=''
adcode:number=0
casts:Array<casts>=[]
}
2.3 城市管理类 2.3 都会管理类
创建一个WeatherModel类来存储访问状态信息,都会信息等
export class WeatherModel{
status:number=0
count:number=0
infocode:number=0
forecasts:Array<forecasts> = []
} 3. 获取数据
通过高德地图API获取指定都会的气候数据,并提供了并发请求多个都会气候的功能。代码中界说了一个getWeatherUtil类,其中包罗两个主要方法:
getWeather(cityCode):这个方法继承一个都会代码作为参数,使用高德地图API的URL模板构建请求URL,并发送HTTP GET请求。假如请求乐成(响应码200),它将解析响应结果并使用Promise的resolve函数返回解析后的气候数据对象WeatherModel。
getWeathers(cityCodes):这是一个异步方法,继承一个都会代码数组,使用getWeather方法为每个都会代码创建一个Promise,并使用Promise.all来并发实行这些Promise。当全部请求都完成后,它会遍历结果,打印每个都会的名字,并返回包罗全部气候数据的WeatherModel数组。
import {casts} from "../viewmodel/casts"
@Component
export struct cityView{
@Builder weatherImage(dayweather: string) {
if (dayweather === "晴") {
Image($r('app.media.sun')).width(30)
}
if (dayweather === "多云") {
Image($r("app.media.cloud")).width(30)
}
if (dayweather === "阴") {
Image($r("app.media.cloud")).width(30)
}
if (dayweather.includes("雨")) {
Image($r("app.media.rain")).width(30)
}
}
//天气数据
casts:Array<casts>=[]
build() {
Column(){
ForEach(this.casts,(cast:casts)=>{
if (this.casts===cast){
//上半部分 图片+当天天气
//图片
Row() {
if (cast.dayweather === "晴") {
Image($r('app.media.sun')).width(260)
}
if (cast.dayweather === "多云") {
Image($r("app.media.cloud")).width(260)
}
if (cast.dayweather === "阴") {
Image($r("app.media.cloud")).width(260)
}
if (cast.dayweather.includes("雨")) {
Image($r("app.media.rain")).width(260)
}
}.height("30%")
Column(){
//温度天气
Row() {
Text(cast.dayweather).fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
Text("" + cast.daytemp + "°~" + cast.nighttemp + "°")
.fontSize(30)
.fontColor(Color.White)
.fontWeight(FontWeight.Bold)
}
//风力
Row() {
Text(cast.daywind + "风").fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
Text(cast.daypower + "级").fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
}
}.margin({ top: 10 })
}
})
//近期天气列表
Column() {
Text("查看近期天气").fontSize(26).margin({ top: 30 })
//天气列表
Row() {
ForEach(this.casts, (cast: casts) => {
Column() {
Text(cast.date.substring(5))
this.weatherImage(cast.dayweather)
Blank()
Text(cast.daytemp.toString())
Line()
.width(20).height(80).startPoint()
.endPoint().stroke(Color.Black)
.strokeWidth(3).strokeDashArray()
Text(cast.nighttemp.toString())
Blank()
this.weatherImage(cast.dayweather)
}.height("90%").width("20%")
})
}
.width("80%")
.height("60%")
.backgroundColor("#ffbab8b8")
.opacity(0.5)
.justifyContent(FlexAlign.SpaceAround)
}.height("45%").width("100%")
}.width("100%").height("100%")
}
}
4. 主页气候数据展示
4.1 主页结构
该项目主页用于展示一个都会气候信息的界面。界面答应用户在差别都会的气候信息之间切换。组件在即将表现时会异步获取气候数据,并更新界面上表现的都会列表和气候信息。用户可以通过点击添加按钮跳转到添加都会的页面,并通过Tab组件检察各个都会的气候详情。以下是主页的结构代码:
import { cityView } from '../view/cityView'
import getWeatherUtil from "../viewmodel/getWeatherUtil"
import {WeatherModel} from "../viewmodel/WeatherModel"
import { router } from '@kit.ArkUI'
@Entry
@Component
struct Index {
//城市代码集合
@State cityCodeList :number[]=
//城市名字集合
@State cityNameList :string[]=[]
//城市信息集合
@State cityWeatherList :Array<WeatherModel>=[]
//当前tab组件索引
@State cityIndex: number = 0
//tab控制器
tabcontroller: TabsController = new TabsController()
//tarBar 自定义函数
@Builder tabBuild(index: number) {
Circle({ width: 10, height: 10 }).fill(this.cityIndex === index ? Color.White : Color.Gray).opacity(0.2)
}
aboutToAppear(){
this.initDate()
}
asyncinitDate(){
// let result :Array<WeatherModel> = getWeatherUtil.getWeathers(this.cityCodeList)
let result :Array<WeatherModel>=await getWeatherUtil.getWeathers(this.cityCodeList)
for (let i = 0; i < result.length; i++) {
let ACityWeather = new WeatherModel()
ACityWeather = result
this.cityWeatherList.push(ACityWeather)
let cityName = result.forecasts.city
this.cityNameList.push(cityName)
}
}
build() {
Column(){
Row(){
Button("添加")
.fontSize(25)
.fontColor(Color.Gray)
.opacity(0.7)
.backgroundColor("#87CEEB")
.margin({ bottom: 15 })
.onClick(() => {
router.pushUrl({
url: "pages/AddCity",
params: {
Codes : this.cityCodeList,
Names : this.cityNameList
}
})
})
Text(this.cityNameList).fontSize(40).fontColor(Color.Orange)
Button("删除")
.fontSize(25)
.fontColor(Color.Gray)
.opacity(0.7)
.backgroundColor("#87CEEB")
.margin({ bottom: 15 })
}.height("10%")
.width("100%")
.justifyContent(FlexAlign.SpaceBetween)
//信息布局
Tabs({ barPosition: BarPosition.Start, controller: this.tabcontroller }) {
ForEach(this.cityWeatherList,(cityWeather:WeatherModel)=>{
TabContent(){
cityView({casts:cityWeather.forecasts.casts})
}.tabBar(this.tabBuild(this.cityWeatherList.findIndex(obj=>obj===cityWeather)))
})
}.barWidth(20)
.barHeight(40)
.onChange((index:number)=>{
this.cityIndex = index
})
}.backgroundColor("#87CEEB")
.width("100%").height("100%")
}
}
[*] 4.2 气候信息展示
在差别的气候信息的展示中用ForEach循环来遍历气候数据数组casts,并为每条气候数据生成对应的视图。界面中包罗了气候图标、温度表现、风力描述以及日期标记,使用差别的结构和样式来优化信息的展示。
import {casts} from "../viewmodel/casts"
@Component
export struct cityView{
@Builder weatherImage(dayweather: string) {
if (dayweather === "晴") {
Image($r('app.media.sun')).width(30)
}
if (dayweather === "多云") {
Image($r("app.media.cloud")).width(30)
}
if (dayweather === "阴") {
Image($r("app.media.cloud")).width(30)
}
if (dayweather.includes("雨")) {
Image($r("app.media.rain")).width(30)
}
}
//天气数据
casts:Array<casts>=[]
build() {
Column(){
ForEach(this.casts,(cast:casts)=>{
if (this.casts===cast){
//上半部分 图片+当天天气
//图片
Row() {
if (cast.dayweather === "晴") {
Image($r('app.media.sun')).width(260)
}
if (cast.dayweather === "多云") {
Image($r("app.media.cloud")).width(260)
}
if (cast.dayweather === "阴") {
Image($r("app.media.cloud")).width(260)
}
if (cast.dayweather.includes("雨")) {
Image($r("app.media.rain")).width(260)
}
}.height("30%")
Column(){
//温度天气
Row() {
Text(cast.dayweather).fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
Text("" + cast.daytemp + "°~" + cast.nighttemp + "°")
.fontSize(30)
.fontColor(Color.White)
.fontWeight(FontWeight.Bold)
}
//风力
Row() {
Text(cast.daywind + "风").fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
Text(cast.daypower + "级").fontSize(30).fontColor(Color.White).fontWeight(FontWeight.Bold)
}
}.margin({ top: 10 })
}
})
//近期天气列表
Column() {
Text("查看近期天气").fontSize(26).margin({ top: 30 })
//天气列表
Row() {
ForEach(this.casts, (cast: casts) => {
Column() {
Text(cast.date.substring(5))
this.weatherImage(cast.dayweather)
Blank()
Text(cast.daytemp.toString())
Line()
.width(20).height(80).startPoint()
.endPoint().stroke(Color.Black)
.strokeWidth(3).strokeDashArray()
Text(cast.nighttemp.toString())
Blank()
this.weatherImage(cast.dayweather)
}.height("90%").width("20%")
})
}
.width("80%")
.height("60%")
.backgroundColor("#ffbab8b8")
.opacity(0.5)
.justifyContent(FlexAlign.SpaceAround)
}.height("45%").width("100%")
}.width("100%").height("100%")
}
}
5. 都会添加与删除
提供用户界面让用户可以或许添加新的都会到都会列表,同样,提供用户界面让用户可以或许从都会列表中删除都会。
import router from '@ohos.router'
interface GeneratedTypeLiteralInterface_1 {
Codes: number[];
}
interface GeneratedTypeLiteralInterface_2 {
Names: string[];
}
@Entry
@Component
struct AddCity {
@State AllCityCodeList :Array<number> =
@State AllCityNameList :Array<string> = ["北京市","天津市","河北省","山西省","辽宁省","吉林省","上海市"]
//当前城市代码列表 接收传入数据的载体
@State cityCodeList :Array<number> = []
@State cityNameList :Array<string> = []
onPageShow(){
let params = router.getParams()
//(user as { name: string }).name
this.cityCodeList = (params as GeneratedTypeLiteralInterface_1).Codes
this.cityNameList = (params as GeneratedTypeLiteralInterface_2).Names
}
build() {
//加入
Column(){
Row(){
Text("添加城市列表").fontSize(35).fontColor(Color.White)
Blank()
Button("完成").backgroundColor("").fontSize(26)
.onClick(()=>{
router.back({
url:"pages/Index",
params:{
Codes:this.cityCodeList
}
})
})
}.height("10%").width("95%")
//城市列表
Column() {
List() {
ForEach(this.AllCityNameList, (name: string) => {
ListItem() {
if (this.cityNameList.includes(name)) {
Column() {
Row() {
Text(name).fontSize(35).fontColor(Color.White).width("60%")
.margin({ top: 20, left: 30 })
Blank()
Text("已添加").backgroundColor("").fontSize(18)
.margin({ right: 5 })
.opacity(0.8)
}.width("100%")
Blank()
Divider().strokeWidth(5)
}.height(90).width("100%").margin({ top: 20 })
.backgroundColor("#4682B4")
} else {
Column() {
Row() {
Text(name).fontSize(35).fontColor(Color.White).width("60%")
.margin({ top: 20, left: 30 })
Blank()
Button("添加").backgroundColor("").fontSize(18)
.margin({ right: 5 })
.onClick(() => {
//根据name 获取所在索引
let index = this.AllCityNameList.findIndex(obj => obj === name)
console.log("index:"+index)
//根据索引获得 城市对应的编码
let cityCode: number = this.AllCityCodeList
console.log("cityCode= "+cityCode)
//将编码加入列表
this.cityCodeList.push(cityCode)
this.cityNameList.push(name)
console.log(this.cityCodeList.toString())
})
}.width("100%")
Blank()
Divider().strokeWidth(5)
}.height(90).width("100%").margin({ top: 20 })
.backgroundColor("#87CEEB")
}
}
})
}
}.width("100%").height("90%")
}.width("100%").height("100%").backgroundColor("#87CEFA")
}
} 6.功能展示
https://i-blog.csdnimg.cn/direct/5b6b0bfccbe440b5b761b42763196be3.png
https://i-blog.csdnimg.cn/direct/1569e12724ac475cb6027314f20e839e.png
7.项目不足与经验总结
7.1项目计划不足
错误处理机制不统一:差别的请求有差别的错误处理方式,缺少统一的管理。
数据缓存策略不美满:缓存过期时间与革新机制不敷灵活,可能导致数据滞后。
网络请求与组件耦合:网络请求和 UI 组件耦合过深,应该解耦。
过度依赖外部 API:对第三方 API 依赖过高,缺少容错机制和备用方案。
UI 计划与用户体验欠缺:UI 交互和细节优化不足,加载提示和数据展示有待改进。
气候数据展示条理不清晰:展示的气候数据缺乏优先级和条理感。
缺少单元测试与主动化测试:缺少美满的单元测试和主动化测试,难以及时发现问题。
7.2经验总结
模块化计划:功能模块化进步代码可维护性和可扩展性。
公道使用数据缓存:优化缓存机制,减少网络请求,进步用户体验。
UI 交互优化:通过动态效果和反馈提拔用户体验。
提前规划错误处理:统一的错误处理机制提拔代码可靠性。
第三方 API 备选方案:避免过度依赖单一 API,增长容错机制。
清晰的数据结构界说:明确数据格式和结构,包管一致性。
可扩展性:计划时考虑将来功能扩展,保持灵活性。
参考与主要借鉴网址:GitHub - YeMengLiChou/LuckWeather-HarmonyApp: 鸿蒙课设开发——好气候App
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]