写点什么

基于 OpenHarmony 开发的玻璃拟态天气应用 (2) 构建当前天气组件

作者:路北路陈
  • 2023-06-20
    江苏
  • 本文字数:5787 字

    阅读完需:约 19 分钟

基于OpenHarmony开发的玻璃拟态天气应用(2)构建当前天气组件

基于 OpenHarmony 开发的玻璃拟态天气应用(2)构建当前天气组件

项目介绍

项目描述

本项目使用了 API9 作为开发版本,该版本是一个较新的版本,在这个项目中我会展示该项目的主要功能构成,主要是展示玻璃拟态的具体开发代码和开发思路,本项目偏向前端开发,后端使用的是和风天气的免费天气 API.

开源地址

整个项目也会同步开源到 Gitee 和 GItHub 仓库中


Gitee:GlassWerther (gitee.com)


GItHub:GlassWeather (github.com)

项目展示

项目设计思路

本项目的设计风格主要学习了 IOS 自带的天气软件,IOS 自带天气的风格就是这种玻璃拟态的风格,个人认为这种风格还是非常好看的,所以本项目大部分代码都是为了实现与其相近的效果

项目主要组件

当前天气组件 NowTemp

该组件显示的内容有以下几部分:当前城市,当前天气,天气描述,今日最高温和最低温

今日空气质量组件 AirQuality

该组件展示了今日的空气质量,主要以展示 AQI 的方式来展示空气质量

卡片组件

该组件包含了数个卡片,卡片中的信息是今日天气指数的一些相关信息,如钓鱼指数等,目的是直观的展示今日天气适合做什么.

搭建项目

构建当前天气组件

创建组件目录

在 ets 目录下创建名为 weatherComponent 的文件目录以方便管理接下来创建的组件


创建当前天气组件的文件

在刚才的目录下创建新的 ArkTS File,命名为 CurrentWeather,如图:



创建后会得到一个空的文件



我们将在此文件中编写我们的自定义组件 CurrentWeather

构建当前天气组件

先添加修饰符@Component并在下面创建对应的结构体组件,代码如下


@Componentexport struct CurrentWeather {  build() {    Column() {
} }}
复制代码


添加修饰符@Preview即可在预览窗口中查看,但不建议这样做,还是建议直接预览主页面而不是预览自定义组件


将该组件导入主页面中即可预览


主页面代码修改为:


import { CurrentWeather } from '../weatherComponent/CurrentWeather'@Entry@Componentstruct Index {  @State message: string = 'Hello World'
build() { Column() { Text('当前天气') .fontSize(50) .fontWeight(FontWeight.Bold) CurrentWeather() Text('今日空气质量') .fontSize(50) .fontWeight(FontWeight.Bold) Text('卡片组件') .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') .justifyContent(FlexAlign.Start) }}
复制代码


添加了之后主页面并没有改变,因为我们现在还没有在自定义组件中写东西,接下来我们继续写自定义组件


先按照图中所示添加对应的文字,并修改格式


代码修改后如下:


@Component // 将当前代码块标记为组件export struct CurrentWeather {  build() {    Column() { // 创建一个列布局      Text('城市名') // 显示城市名        .fontSize(30) // 设置字体大小        .margin({ // 设置边距          top: 60,          bottom: 0        })        .fontColor(Color.Black) // 设置字体颜色        .fontWeight(400) // 设置字体粗细      Text('经纬度') // 显示经纬度        .fontSize(12) // 设置字体大小        .margin({ // 设置边距          top: 10        })        .fontColor(Color.Black) // 设置字体颜色        .fontWeight(200) // 设置字体粗细      Text('当前温度') // 显示当前温度        .fontSize(80) // 设置字体大小        .fontWeight(200) // 设置字体粗细        .fontColor(Color.Black) // 设置字体颜色      Text('当前天气描述') // 显示当前天气描述        .fontSize(18) // 设置字体大小        .fontWeight(500) // 设置字体粗细        .margin({ // 设置边距          bottom: 10        })        .fontColor(Color.Black) // 设置字体颜色      Text('最高温 最低温') // 显示最高温和最低温        .fontSize(18) // 设置字体大小        .fontWeight(500) // 设置字体粗细        .margin({ // 设置边距          bottom: 10        })        .fontColor(Color.Black) // 设置字体颜色    }  }}
复制代码


效果如下:



如果我们想修改字体颜色,就要一个一个修改,维护难度非常大,所以我们可以将需要用到的颜色写在src/main/resources/base/element/color.json中,这样就能适用$r()的格式来引用资源了


我们先在这个文件中添加我们需要的颜色


修改后如下:


{  "color": [    {      "name": "start_window_background",      "value": "#FFFFFF"    },    {      "name": "baseFontColor",      "value": "#000000"    }  ]}
复制代码


然后我们改自定义组件的代码,修改后如下:


@Component // 将当前代码块标记为组件export struct CurrentWeather {  build() {    Column() { // 创建一个列布局      Text('城市名') // 显示城市名        .fontSize(30) // 设置字体大小        .margin({ // 设置边距          top: 60,          bottom: 0        })        .fontColor($r('app.color.baseFontColor')) // 设置字体颜色        .fontWeight(400) // 设置字体粗细      Text('经纬度') // 显示经纬度        .fontSize(12) // 设置字体大小        .margin({ // 设置边距          top: 10        })        .fontColor($r('app.color.baseFontColor')) // 设置字体颜色        .fontWeight(200) // 设置字体粗细      Text('当前温度') // 显示当前温度        .fontSize(80) // 设置字体大小        .fontWeight(200) // 设置字体粗细        .fontColor($r('app.color.baseFontColor')) // 设置字体颜色      Text('当前天气描述') // 显示当前天气描述        .fontSize(18) // 设置字体大小        .fontWeight(500) // 设置字体粗细        .margin({ // 设置边距          bottom: 10        })        .fontColor($r('app.color.baseFontColor')) // 设置字体颜色      Text('最高温 最低温') // 显示最高温和最低温        .fontSize(18) // 设置字体大小        .fontWeight(500) // 设置字体粗细        .margin({ // 设置边距          bottom: 10        })        .fontColor($r('app.color.baseFontColor')) // 设置字体颜色    }  }}
复制代码


这样我们当前温度的前端框架就基本完成了


接下来我们要使用 axios 来编写后端请求,来完成对天气的请求

编写 API 请求

导入 axios

E:\Works\DevoEcoProjects\GlassWeather\oh-package.json5中添加 axios 组件,修改后的代码为


{  "name": "glassweather",  "version": "1.0.0",  "description": "Please describe the basic information.",  "main": "",  "author": "",  "license": "",  "dependencies": {    "@ohos/axios": "^2.0.0"  },  "devDependencies": {    "@ohos/hypium": "1.0.6",    "@ohos/axios": "^2.0.0"  }}
复制代码


最后在需要使用 axios 的地方添加


import axios from '@ohos/axios'
复制代码
添加权限

API 请求是一个网络请求,所以需要给这个请求添加系统级的权限


E:\Works\DevoEcoProjects\GlassWeather\entry\src\main\module.json5中添加权限


"requestPermissions": [      {        "name": "ohos.permission.INTERNET"      }    ],
复制代码


修改后的完整代码如下


{  "module": {    "name": "entry",    "type": "entry",    "description": "$string:module_desc",    "mainElement": "EntryAbility",    "deviceTypes": [      "phone"    ],    "requestPermissions": [      {        "name": "ohos.permission.INTERNET"      }    ],    "deliveryWithInstall": true,    "installationFree": false,    "pages": "$profile:main_pages",    "abilities": [      {        "name": "EntryAbility",        "srcEntry": "./ets/entryability/EntryAbility.ts",        "description": "$string:EntryAbility_desc",        "icon": "$media:icon",        "label": "$string:EntryAbility_label",        "startWindowIcon": "$media:icon",        "startWindowBackground": "$color:start_window_background",        "exported": true,        "skills": [          {            "entities": [              "entity.system.home"            ],            "actions": [              "action.system.home"            ]          }        ]      }    ]  }}
复制代码
添加模型

需要添加模型来将之后接收到的数据转换为对象的格式,方便调用


E:\Works\DevoEcoProjects\GlassWeather\entry\src\main\ets目录下创建一个新的文件夹,命名为 model


在 model 下创建 ArkTS File 命名为 WeatherModel


在该文件中根据和风天气的开发文档创建对应的模型


修改后的代码如下:


export class CurrentWeatherModel {  obsTime?: string // 数据观测时间  temp?: string // 温度,默认单位:摄氏度  feelsLike?: string // 体感温度,默认单位:摄氏度  icon?: string // 天气状况和图标的代码,图标可通过天气状况和图标下载  text?: string // 天气状况的文字描述,包括阴晴雨雪等天气状态的描述  wind360?: string // 风向360角度  windDir?: string // 风向  windScale?: string // 风力等级  temperature?: string // 温度  direct?: string // 风向  windSpeed?: string // 风速,公里/小时  humidity?: string // 相对湿度,百分比数值  precip?: string // 当前小时累计降水量,默认单位:毫米  pressure?: string //大气压强,默认单位:百帕  vis?: string // 能见度,默认单位:公里  cloud?: string //   云量,百分比数值。可能为空  dew?: string // 露点温度。可能为空}
复制代码
编写请求

参考和风天气的开发文档,使用 axios 编写请求


编写的请求如下:


  getCurrentWeather() {    let weatherUrl = 'https://devapi.qweather.com/v7/weather/now?location=116,40&key=9243123252294a3e93ae6ccab5ec5da7';    // 发起天气请求    axios.get(weatherUrl)      .then(res => {        let data = JSON.stringify(res.data.now);        let currentWeatherModel: CurrentWeatherModel = JSON.parse(data.toString());
}); }
复制代码


编写玩成后需要将这个请求放在页面渲染时的函数中,对应的函数是aboutToAppear()


即在代码中添加


  aboutToAppear(){    this.getCurrentWeather()  }
复制代码


给这个组件添加全局的变量,在获取到数据后可以自动更新页面


修改后的完整代码如下:


import axios from '@ohos/axios'import { CurrentWeatherModel } from '../model/WeatherModel';
@Component // 将当前代码块标记为组件export struct CurrentWeather { @State temp: string = 'temp' @State text: string = 'text'
aboutToAppear(){ this.getCurrentWeather() }
getCurrentWeather() { let weatherUrl = 'https://devapi.qweather.com/v7/weather/now?location=116,40&key=9243123252294a3e93ae6ccab5ec5da7'; // 发起天气请求 axios.get(weatherUrl) .then(res => { let data = JSON.stringify(res.data.now); let currentWeatherModel: CurrentWeatherModel = JSON.parse(data.toString()); this.temp = currentWeatherModel.temp this.text = currentWeatherModel.text }); }
build() { Column() { // 创建一个列布局 Text('城市名') // 显示城市名 .fontSize(30) // 设置字体大小 .margin({ // 设置边距 top: 60, bottom: 0 }) .fontColor($r('app.color.baseFontColor')) // 设置字体颜色 .fontWeight(400) // 设置字体粗细 Text('经纬度') // 显示经纬度 .fontSize(12) // 设置字体大小 .margin({ // 设置边距 top: 10 }) .fontColor($r('app.color.baseFontColor')) // 设置字体颜色 .fontWeight(200) // 设置字体粗细 Text(`${this.temp}°`) // 显示当前温度 .fontSize(80) // 设置字体大小 .fontWeight(200) // 设置字体粗细 .fontColor($r('app.color.baseFontColor')) // 设置字体颜色 Text(this.text) // 显示当前天气描述 .fontSize(18) // 设置字体大小 .fontWeight(500) // 设置字体粗细 .margin({ // 设置边距 bottom: 10 }) .fontColor($r('app.color.baseFontColor')) // 设置字体颜色 Text('最高温 最低温') // 显示最高温和最低温 .fontSize(18) // 设置字体大小 .fontWeight(500) // 设置字体粗细 .margin({ // 设置边距 bottom: 10 }) .fontColor($r('app.color.baseFontColor')) // 设置字体颜色 } }}
复制代码


效果如图:


总结

以上内容是一个使用 Ark UI 框架搭建的当前天气组件的示例。


首先,我们创建了一个名为 weatherComponent 的文件目录,并在其中创建了一个名为 CurrentWeather 的组件文件。


然后,在 CurrentWeather 组件中,我们使用了@Component修饰符来标识这是一个组件,并使用了@State修饰符来定义了两个状态变量 temp 和 text。


在组件的build方法中,我们使用了Column来创建一个垂直的列布局,并在其中添加了多个Text组件来显示城市名、经纬度、当前温度、当前天气描述以及最高温和最低温。我们还使用了@r()来引用颜色资源,并使用了aboutToAppear()方法来在页面渲染前获取当前天气数据。


在获取当前天气数据的getCurrentWeather()方法中,我们使用了 axios 库发起了一个 GET 请求,获取了天气数据,并将其转换为 CurrentWeatherModel 对象,并更新了组件的 temp 和 text 状态变量。


最后,我们将 CurrentWeather 组件导入到主页面中,并在页面渲染时使用了这个组件。


总结起来,以上内容是一个使用 Ark UI 框架搭建的当前天气组件,其中包括了组件的构建、样式设置、状态管理以及与后端 API 的交互。通过这个示例,我们可以了解到如何使用 Ark UI 框架来构建自定义组件,并与后端 API 进行数据交互。


完事开头难.如果这一部分的请求都已经完成,那么这个项目的基本流程就已经打通,后面的部分就会相对简单了

发布于: 2023-06-20阅读数: 30
用户头像

路北路陈

关注

还未添加个人签名 2023-06-10 加入

还未添加个人简介

评论

发布
暂无评论
基于OpenHarmony开发的玻璃拟态天气应用(2)构建当前天气组件_前端_路北路陈_InfoQ写作社区