基于 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 进行数据交互。
完事开头难.如果这一部分的请求都已经完成,那么这个项目的基本流程就已经打通,后面的部分就会相对简单了
评论