基于 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
并在下面创建对应的结构体组件,代码如下
@Component
export struct CurrentWeather {
build() {
Column() {
}
}
}
复制代码
添加修饰符@Preview
即可在预览窗口中查看,但不建议这样做,还是建议直接预览主页面而不是预览自定义组件
将该组件导入主页面中即可预览
主页面代码修改为:
import { CurrentWeather } from '../weatherComponent/CurrentWeather'
@Entry
@Component
struct 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 进行数据交互。
完事开头难.如果这一部分的请求都已经完成,那么这个项目的基本流程就已经打通,后面的部分就会相对简单了
评论