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

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
}

2.2 城市管理类

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

export class forecasts{
  city:string=''
  adcode:number=0
  casts:Array<casts>=[]
}

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

export class WeatherModel{
  status:number=0
  count:number=0
  infocode:number=0
  forecasts:Array<forecasts> = []
}

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%")
 
  }
 
}
 

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%")
  }
}

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%")
 
  }
 
}

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")
  }
}

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

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