HarmonyOS 5开发从入门到精通(十五):天气应用实战(上)
HarmonyOS 5开发从入门到精通(十五):天气应用实战(上)
本章将带领大家开发一个完整的天气应用,涵盖网络请求、JSON解析、UI展示等核心功能。通过本案例,你将掌握HarmonyOS应用开发的关键技能。
一、核心概念
1. 网络请求与数据模型
天气应用的核心是获取远程API数据并转换为本地数据模型。HarmonyOS提供了@ohos.net.http模块进行网络请求,配合JSON解析将服务器返回的数据转换为TypeScript对象,实现数据驱动UI。
2. 城市搜索与数据筛选
城市搜索功能通过监听输入框变化,实时过滤城市列表。结合ArkUI的响应式特性,当搜索关键词变化时,界面自动更新显示匹配结果。
二、关键API详解
1. 网络请求模块
import http from '@ohos.net.http'
// 创建HTTP请求实例
const httpRequest = http.createHttp()
// 发起GET请求
httpRequest.request(url, {
method: http.RequestMethod.GET,
connectTimeout: 10000,
readTimeout: 10000
})
2. JSON解析
// 解析JSON字符串
const weatherData = JSON.parse(response.result)
// 转换为JSON字符串
const jsonStr = JSON.stringify(weatherData)
3. 天气数据模型
class WeatherModel {
city: string = ''
temperature: number = 0
condition: string = ''
humidity: number = 0
windSpeed: number = 0
}
4. 城市搜索过滤
// 过滤城市列表
const filteredCities = cityList.filter(city =>
city.name.includes(searchText)
)
5. 列表组件渲染
List() {
ForEach(this.cityList, (city: CityInfo) => {
ListItem() {
Text(city.name)
}
})
}
6. 输入框组件
TextInput()
.placeholder('搜索城市')
.onChange((value: string) => {
this.searchText = value
})
7. 异步数据获取
async getWeatherData(city: string): Promise<WeatherModel> {
try {
const response = await httpRequest.request(url)
return JSON.parse(response.result)
} catch (error) {
console.error('获取天气数据失败')
}
}
8. 权限配置
{
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
9. 状态管理
@State weatherData: WeatherModel = new WeatherModel()
@State cityList: CityInfo[] = []
@State searchText: string = ''
10. 页面生命周期
aboutToAppear() {
this.loadWeatherData()
}
onPageShow() {
this.refreshData()
}
11. 错误处理
try {
// 网络请求
} catch (error) {
console.error('请求失败:', error)
}
12. 数据绑定
Text(this.weatherData.temperature + '°C')
.fontSize(48)
.fontColor(Color.White)
三、实战案例
完整代码实现
import http from '@ohos.net.http'
import { WeatherModel } from '../model/WeatherModel'
@Entry
@Component
struct WeatherApp {
@State weatherData: WeatherModel = new WeatherModel()
@State cityList: CityInfo[] = []
@State searchText: string = ''
@State filteredCities: CityInfo[] = []
private httpRequest = http.createHttp()
aboutToAppear() {
this.loadCities()
this.loadWeatherData('北京')
}
// 加载城市列表
private loadCities() {
this.cityList = [
{ name: '北京', code: '101010100' },
{ name: '上海', code: '101020100' },
{ name: '广州', code: '101280101' },
{ name: '深圳', code: '101280601' },
{ name: '杭州', code: '101210101' }
]
this.filteredCities = this.cityList
}
// 获取天气数据
private async loadWeatherData(city: string) {
try {
const url = `https://api.example.com/weather?city=${city}`
const response = await this.httpRequest.request(url, {
method: http.RequestMethod.GET
})
if (response.responseCode === 200) {
const data = JSON.parse(response.result)
this.weatherData = {
city: data.city,
temperature: data.temp,
condition: data.condition,
humidity: data.humidity,
windSpeed: data.windSpeed
}
}
} catch (error) {
console.error('获取天气数据失败:', error)
}
}
// 搜索城市
private searchCities() {
if (this.searchText === '') {
this.filteredCities = this.cityList
} else {
this.filteredCities = this.cityList.filter(city =>
city.name.includes(this.searchText)
)
}
}
build() {
Column() {
// 搜索框
TextInput()
.placeholder('搜索城市')
.width('90%')
.height(40)
.backgroundColor(Color.White)
.margin({ top: 20 })
.onChange((value: string) => {
this.searchText = value
this.searchCities()
})
// 城市列表
List() {
ForEach(this.filteredCities, (city: CityInfo) => {
ListItem() {
Text(city.name)
.fontSize(18)
.margin({ left: 20 })
}
.onClick(() => {
this.loadWeatherData(city.name)
})
})
}
.width('100%')
.height('60%')
// 天气信息展示
Column() {
Text(this.weatherData.city)
.fontSize(24)
.fontColor(Color.White)
Text(this.weatherData.temperature + '°C')
.fontSize(48)
.fontColor(Color.White)
.margin({ top: 10 })
Text(this.weatherData.condition)
.fontSize(16)
.fontColor(Color.White)
.margin({ top: 5 })
Row() {
Text('湿度: ' + this.weatherData.humidity + '%')
.fontSize(14)
.fontColor(Color.White)
Text('风速: ' + this.weatherData.windSpeed + 'm/s')
.fontSize(14)
.fontColor(Color.White)
.margin({ left: 20 })
}
.margin({ top: 10 })
}
.width('100%')
.height('30%')
.backgroundColor('#4A90E2')
.padding(20)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
// 城市信息模型
interface CityInfo {
name: string
code: string
}
四、总结
✅ 关键知识点
- 网络请求的异步处理与错误捕获
- JSON数据的解析与模型转换
- 城市搜索功能的实时过滤实现
- 数据驱动UI的响应式更新机制
🔧 核心API列表
http.createHttp()- 创建HTTP请求实例http.RequestMethod.GET- GET请求方法JSON.parse()- JSON字符串解析JSON.stringify()- 对象转JSON字符串TextInput().onChange()- 输入框变化监听ForEach()- 列表数据循环渲染@State- 状态管理装饰器async/await- 异步编程语法糖
💡 应用建议
- 网络请求建议使用
try-catch包裹,处理网络异常 - 城市搜索可添加防抖优化,避免频繁触发过滤
- 天气数据可添加本地缓存,提升用户体验
- 建议使用真实的天气API(如和风天气、高德天气)替换示例中的模拟接口
通过本章学习,你已经掌握了天气应用的核心开发技能。下一章我们将继续完善应用,添加更多实用功能。
浙公网安备 33010602011771号