#HarmonyOS NEXT体验官# 基于HTTP的列表数据加载(一)
基于HTTP的列表数据加载(一)
在移动应用开发中,列表式的数据展示页面是最为常见的业务场景之一。比如商品列表、新闻列表、任务列表等。列表这种形式可以在移动端屏幕上将数据清晰地呈现给用户。但是像商品、新闻这类的数据往往都是需要实时更新的,因此不能使用本地的数据,而是要通过网络请求实时的从服务器上获取新的数据。
程序效果
上图中展示了一个商品列表程序的界面。
- 左侧界面为商品列表首页。在进入首页后,页面会自动发送HTTP请求都服务端获取商品列表数据。然后从获取到的列表中,将商品信息依次显示在页面中。可以看到每一个商品信息都是放在一个独立的卡片模块中,他们的格式是相同的。
- 当用户点击任意一个商品的描述文字后(也可以设置为点击整个卡片),页面会跳转到对应商品的详情页(分别对应右侧两个页面)。
- 进入详情页后,同样通过HTTP请求获取对应商品的详情信息,并显示在页面中。
项目结构
本项目的目录结构如下图所示。
- 在pages目录中包含两个页面文件:Index.ets对应商品列表页,负责展示商品列表的逻辑;Detail.ets对应详情页,展示商品详细信息。
- components目录中的GoodItem.ets是一个自定义的商品列表项目组件,供商品列表页渲染每一个商品项目时使用。
- Types目录中的GoodsTypes文件中定义商品数据相关的各种类型(在本例中只声明了一个商品信息的接口类型)。通过将类型声明在公共文件中,便于其他组件使用。
目录结构如下图:
开启网络权限
鸿蒙应用在访问网络资源前,首先需要开启应用的网络访问权限。如果不开启则无法进行网络请求。
网络访问权限的配置信息位于程序所属模块下的src/main/module.json5
文件中。
本程序使用的是默认的entry模块。如果在其他模块中需要进行网络请求,请修改对应模块下的module.json5文件。
在module.json5文件中,请在module配置对象中的requestPermissions
数组(如果没有,请自行增加该属性)中增加一个新对象。该对象有一个名为name
的属性,其值为ohos.permission.INTERNET
。示例如下:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
// 其他配置的属性...
}
}
完成配置后,即可在当前模块的页面中正常使用网络请求功能。
程序实现
下面我们来看一下程序中的代码。首先是GoodItem.ets和GoodsTypes.ets这两个文件的代码。他们比较简单,且会在其他组件中被使用。因此在看主要业务逻辑之前我们需要先了解这两个文件的内容。他们的作用一个提供公共类型,一个提供公共组件。
GoodTypes.ets代码
在此文件中定义商品数据中的信息。
/**
* 声明商品信息的数据接口,确定商品数据能提供的属性。
* @goodName: 商品名称
* @goodPrice: 商品价格
* @imgUrl: 商品图片链接
* @id: 商品id
* @description: 商品描述
*/
export interface GoodInfo {
goodName: string
goodPrice: string
imgUrl: string
id: string
description: string
}
GoodItem.ets代码
import { router } from '@kit.ArkUI'
import { GoodInfo } from '../Types/GoodsTypes'
@Component
export default struct GoodItem {
@Prop goodInfo: GoodInfo
build() {
Row(){
Column(){
Image(this.goodInfo.imgUrl)
.objectFit(ImageFit.Contain)
}
.width('28%')
.height('100%')
Column(){
Text(this.goodInfo.goodName)
.fontWeight('bold')
.fontSize('60px')
Text(this.goodInfo.goodPrice)
.margin({bottom:'20px'})
.fontColor('red')
Text(this.goodInfo.description)
// 代码1)
.onClick(() => {
router.pushUrl({
url: `pages/Detail`,
params: {
id: this.goodInfo.id
}
})
})
.maxLines(3)
.textOverflow({overflow: TextOverflow.Ellipsis})
}
.alignItems(HorizontalAlign.Start)
.width('68%')
.padding({top:'10px'})
}
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Top)
.width('90%')
.height('400px')
.padding('20px')
.margin({top:10})
.shadow({radius:20, offsetY:8, offsetX:5, color:'gray'})
.borderRadius(10)
}
}
GoodItem的代码创建了一个GoodItem组件。组件布局和样式如下:
在最开始的页面设计中可以看出,商品列表中每一个商品项目都是类似上图的一个独立的区域。每个区域内部的布局和工作逻辑一致。因此将这个区域的结构内容和逻辑提取出来封装成一个公共组件是一个很好地选择。
GoodItem组件通@prop
的goodInfo属性
从父组件接收商品的信息后,根据商品信息绘制页面内容。
另外,代码1)
处点击描述文字时的响应事件逻辑如下:当点击描述文字时,会调用router组件跳转到Detail页面。跳转的同时向Detail页面传送一个id
参数。id
的值为用户点击的商品项目所对应的商品id。
未完待续…
在本文的第二篇中,我们将继续分析Index.ets和Detail.ets中的代码。请感兴趣的同学继续关注。