【中工开发者】鸿蒙——天气服务

wx676266ee6b525
发布于 2024-12-18 15:07
浏览
0收藏

简介

我是中原工学院的一名学生,通过学习鸿蒙课程所做了一款服务软件。Weather service(天气服务)是一个用于鸿蒙应用中其手机查询天气的工具库。通过使用Weather service,开发者可以在鸿蒙应用中提供天气查询的功能,用户可以自行查询所在地的天气。该服务为用户提供简单天气查询体验。

1. 数据接口获取

在开发天气查询应用之前,我们需要一个可靠的天气数据接口。这里我们可以选择公开的天气API,如高德地图、和风天气等。以高德地图为例,我们需要注册账号并获取一个API密钥(API Key),用于后续的数据请求。

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
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

2.2 城市管理类

创建一个forecasts类来存储城市名称,代码,天气信息:

export class forecasts{
  city:string=''
  adcode:number=0
  casts:Array<casts>=[]
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

创建一个WeatherModel类来存储访问状态信息,城市信息等

export class WeatherModel{
  status:number=0
  count:number=0
  infocode:number=0
  forecasts:Array<forecasts> = []
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

3. 获取天气数据

通过高德地图API获取指定城市的天气数据,并提供了并发请求多个城市天气的功能。

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[0]===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([10, 0])
                .endPoint([10, 70]).stroke(Color.Black)
                .strokeWidth(3).strokeDashArray([10, 3])
              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%")
 
  }
 
}
 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.

4. 主页天气展示

4.1 主页布局

该项目主页用于展示一个城市天气信息的界面。界面允许用户在不同城市的天气信息之间切换。组件在即将显示时会异步获取天气数据,并更新界面上显示的城市列表和天气信息。

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[]=[110000,120000,130000]
  //城市名字集合
  @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()
 
  }
 async  initDate(){
    // 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[i]
     this.cityWeatherList.push(ACityWeather)
     let cityName = result[i].forecasts[0].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[this.cityIndex]).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[0].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%")
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.

4.2 天气信息展示

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[0]===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([10, 0])
                .endPoint([10, 70]).stroke(Color.Black)
                .strokeWidth(3).strokeDashArray([10, 3])
              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%")
 
  }
 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.

4.3 城市添加和删除

提供用户界面让用户能够添加新的城市到城市列表,同样,提供用户界面让用户能够从城市列表中删除城市。

import router from '@ohos.router'
 
interface GeneratedTypeLiteralInterface_1 {
  Codes: number[];
}
 
interface GeneratedTypeLiteralInterface_2 {
  Names: string[];
}
 
@Entry
@Component
struct AddCity {
 
  @State AllCityCodeList :Array<number> = [110000,120000,130000,140000,210000,220000,310000]
  @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[index]
                        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")
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.

【中工开发者】鸿蒙——天气服务-鸿蒙开发者社区

分类
收藏
回复
举报
回复
    相关推荐