1. 安装依赖包
ohpm install @ohos/axios @ohos/pulltorefresh@2.0.1
2. 页面布局
@Entry
@Component
struct Index {
build() {
Column() {
Row() {
Image($r("app.media.left"))
.height(16)
.position({
x: 10,
y: 16
})
Text("新闻列表")
.width("100%")
.height(50)
.fontSize(18)
.textAlign(TextAlign.Center)
}
.width("100%")
.height(50)
Column() {
// 新闻列表
}
.backgroundColor(Color.Red)
.width('100%')
.layoutWeight(1)
}
.width("100%")
.height("100%")
}
}
3. 上拉加载更多/下拉更新
3.1 引入插件
import { PullToRefresh } from '@ohos/pulltorefresh'
import axios from "@ohos/axios"
3.2 添加新闻数据类型
export interface News {
name?: string
}
3.3 创建 scroller 控制器
private scroller: Scroller = new Scroller();
3.4 添加新闻列表数据
@State newsList: News[] = []
3.5 添加组件
PullToRefresh({
// 必传项,列表组件所绑定的数据
data: $newsList,
// 必传项,需绑定传入主体布局内的列表或宫格组件
scroller: this.scroller,
// 必传项,自定义主体布局,内部有列表或宫格组件
customList: () => {
this.buildNewsList();
},
customLoad: null,
customRefresh: null
})
3.6 添加 buildNewsList 方法
@Builder
buildNewsList() {
List({ scroller: this.scroller }) {
ForEach(this.newsList, (item: News, index: number) => {
ListItem() {
Text(`${index + 1} -- ${item.name}`)
.width("100%")
.height(100)
.padding(10)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
})
}
.divider({
strokeWidth: 1,
color: "#ddd"
})
.edgeEffect(EdgeEffect.None)
}
3.7 添加api接口获取新闻数据
// 分页
@State page: number = 1
// 是否还有更多
@State hasMore: boolean = true
aboutToAppear() {
this.fetchNewsData()
}
async fetchNewsData(resolve?: (value: string | PromiseLike<string>) => void) {
if (!this.hasMore) {
resolve?.('true')
return
}
const apiUrl = 'https://api.thepaper.cn/contentapi/nodeCont/getByChannelId'
const res = await axios.post(apiUrl, {
channelId: "119908",
excludeContIds: [27131749, 27132788, 27142995],
listRecommendIds: [27142995, 27131749],
pageNum: this.page,
pageSize: 10,
province: null,
startTime: 1713577612993,
})
const result: News[] = res.data.data.list
this.newsList = this.newsList.concat(result)
this.page++
// 判断有没有数据
if (this.page > 5) {
this.hasMore = false
}
resolve?.('true')
}
3.8 添加上拉加载方法
// 可选项,上拉加载更多回调
onLoadMore: () => {
return new Promise<string>((resolve) => {
return this.fetchNewsData(resolve)
});
},
3.9 添加下拉刷新
// 可选项,下拉刷新回调
onRefresh: () => {
return new Promise<string>((resolve) => {
this.hasMore = true
this.page = 1
this.newsList = []
return this.fetchNewsData(resolve)
});
},
4. 完整代码
import { PullToRefresh } from '@ohos/pulltorefresh'
import axios from "@ohos/axios"
export interface News {
name?: string
}
@Entry
@Component
struct Index {
private scroller: Scroller = new Scroller();
@State newsList: News[] = []
// 分页
@State page: number = 1
// 是否还有更多
@State hasMore: boolean = true
aboutToAppear() {
this.fetchNewsData()
}
async fetchNewsData(resolve?: (value: string | PromiseLike<string>) => void) {
if (!this.hasMore) {
resolve?.('true')
return
}
const apiUrl = 'https://api.thepaper.cn/contentapi/nodeCont/getByChannelId'
const res = await axios.post(apiUrl, {
channelId: "119908",
excludeContIds: [27131749, 27132788, 27142995],
listRecommendIds: [27142995, 27131749],
pageNum: this.page,
pageSize: 10,
province: null,
startTime: 1713577612993,
})
const result: News[] = res.data.data.list
this.newsList = this.newsList.concat(result)
this.page++
// 判断有没有数据
if (this.page > 5) {
this.hasMore = false
}
resolve?.('true')
}
@Builder
buildNewsList() {
List({ scroller: this.scroller }) {
ForEach(this.newsList, (item: News, index: number) => {
ListItem() {
Text(`${index + 1} -- ${item.name}`)
.width("100%")
.height(100)
.padding(10)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
})
}
.divider({
strokeWidth: 1,
color: "#ddd"
})
.edgeEffect(EdgeEffect.None)
}
build() {
Column() {
Row() {
Image($r("app.media.left"))
.height(16)
.position({
x: 10,
y: 16
})
Text("新闻列表")
.width("100%")
.height(50)
.fontSize(18)
.textAlign(TextAlign.Center)
}
.width("100%")
.height(50)
Column() {
// 新闻列表
PullToRefresh({
// 必传项,列表组件所绑定的数据
data: $newsList,
// 必传项,需绑定传入主体布局内的列表或宫格组件
scroller: this.scroller,
// 必传项,自定义主体布局,内部有列表或宫格组件
customList: () => {
this.buildNewsList();
},
// 可选项,下拉刷新回调
onRefresh: () => {
return new Promise<string>((resolve) => {
this.hasMore = true
this.page = 1
this.newsList = []
return this.fetchNewsData(resolve)
});
},
// 可选项,上拉加载更多回调
onLoadMore: () => {
return new Promise<string>((resolve) => {
return this.fetchNewsData(resolve)
});
},
customLoad: null,
customRefresh: null
})
}
.width('100%')
.layoutWeight(1)
}
.width("100%")
.height("100%")
}
}