HarmonyOS 鸿蒙Next中List组件实现下拉刷新和上拉加载更多
HarmonyOS 鸿蒙Next中List组件实现下拉刷新和上拉加载更多 需要实现案例列表的分页加载,支持下拉刷新和滚动到底部自动加载更多。
3 回复
原理解析
Refresh组件:包裹List实现下拉刷新onReachEnd事件:List滚动到底部时触发- 分页参数:维护当前页码和是否还有更多数据
解决方案
interface CaseListItem {
caseId: string;
title: string;
phenomenon: string;
tags: string[];
}
@Entry
@Component
struct CaseListPage {
@State caseList: CaseListItem[] = [];
@State isLoading: boolean = false;
@State isRefreshing: boolean = false;
@State hasMore: boolean = true;
@State currentPage: number = 1;
private pageSize: number = 20;
aboutToAppear(): void {
this.loadData(true);
}
async loadData(isRefresh: boolean = false): Promise<void> {
if (this.isLoading) return;
if (isRefresh) {
this.currentPage = 1;
this.hasMore = true;
}
if (!this.hasMore && !isRefresh) return;
this.isLoading = true;
try {
// 模拟API请求
const result = await this.fetchCases(this.currentPage, this.pageSize);
if (isRefresh) {
this.caseList = result.list;
} else {
this.caseList = [...this.caseList, ...result.list];
}
this.hasMore = result.list.length >= this.pageSize;
if (this.hasMore) {
this.currentPage++;
}
} catch (e) {
console.error('加载失败', e);
} finally {
this.isLoading = false;
this.isRefreshing = false;
}
}
async fetchCases(page: number, size: number): Promise<{ list: CaseListItem[] }> {
// 实际项目中调用数据库或API
const allCases = await caseDao.getList();
const start = (page - 1) * size;
const end = start + size;
return { list: allCases.slice(start, end) };
}
build() {
Column() {
// 顶部导航栏
Row() {
Text('案例库')
.fontSize(18)
.fontWeight(FontWeight.Bold)
Blank()
Text(`共 ${this.caseList.length} 条`)
.fontSize(13)
.fontColor('#999999')
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
// 下拉刷新 + 列表
Refresh({ refreshing: $$this.isRefreshing }) {
List() {
ForEach(this.caseList, (item: CaseListItem) => {
ListItem() {
this.CaseCard(item)
}
.padding({ left: 16, right: 16, bottom: 12 })
}, (item: CaseListItem) => item.caseId)
// 底部加载状态
ListItem() {
this.LoadMoreFooter()
}
}
.width('100%')
.layoutWeight(1)
.divider({ strokeWidth: 0 })
.onReachEnd(() => {
// 滚动到底部,加载更多
if (!this.isLoading && this.hasMore) {
this.loadData(false);
}
})
}
.onRefreshing(() => {
// 下拉刷新
this.loadData(true);
})
}
.width('100%')
.height('100%')
}
@Builder
CaseCard(item: CaseListItem) {
Column({ space: 8 }) {
Text(item.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Text(item.phenomenon)
.fontSize(13)
.fontColor('#666666')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Row({ space: 6 }) {
ForEach(item.tags.slice(0, 3), (tag: string) => {
Text(tag)
.fontSize(11)
.fontColor('#1890FF')
.backgroundColor('#E6F7FF')
.padding({ left: 8, right: 8, top: 3, bottom: 3 })
.borderRadius(4)
})
}
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
.borderRadius(12)
.alignItems(HorizontalAlign.Start)
}
@Builder
LoadMoreFooter() {
Row() {
if (this.isLoading) {
LoadingProgress().width(20).height(20)
Text('加载中...').fontSize(13).fontColor('#999999').margin({ left: 8 })
} else if (!this.hasMore) {
Text('— 没有更多了 —').fontSize(13).fontColor('#CCCCCC')
}
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}
}
更多关于HarmonyOS 鸿蒙Next中List组件实现下拉刷新和上拉加载更多的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,List组件通过refresh和loadMore事件实现下拉刷新和上拉加载。使用List的onScrollIndex监听滚动位置触发加载更多。下拉刷新通常结合Refresh组件,通过onRefresh回调更新数据。上拉加载在列表滚动到底部时触发,更新数据源并重新渲染列表。
在HarmonyOS Next中,可以使用List组件配合Refresh和List的onReachEnd事件来实现下拉刷新与上拉加载更多。以下是核心实现方案:
1. 下拉刷新
使用Refresh组件包裹List,通过onRefresh回调触发数据刷新。
Refresh({
refreshing: this.isRefreshing, // 控制刷新状态
onRefresh: () => {
this.isRefreshing = true;
// 执行刷新逻辑,如重新请求第一页数据
this.loadData(true);
}
}) {
List() {
// 列表内容
}
}
2. 上拉加载更多
监听List的onReachEnd事件,触发时加载下一页数据。
List() {
// 列表项
}
.onReachEnd(() => {
if (!this.isLoading && this.hasMore) {
this.isLoading = true;
// 执行加载更多逻辑
this.loadData(false);
}
})
3. 状态管理
需要维护的关键状态:
isRefreshing: 控制刷新动画isLoading: 防止重复加载hasMore: 是否还有更多数据pageIndex: 当前页码
4. 数据加载函数示例
async loadData(isRefresh: boolean) {
if (isRefresh) {
this.pageIndex = 1;
} else {
this.pageIndex += 1;
}
try {
const newData = await this.fetchData(this.pageIndex);
if (isRefresh) {
this.data = newData;
} else {
this.data = this.data.concat(newData);
}
this.hasMore = newData.length >= PAGE_SIZE;
} catch (error) {
// 错误处理
} finally {
this.isRefreshing = false;
this.isLoading = false;
}
}
5. 完整组件结构
struct ListWithRefresh {
@State data: Item[] = [];
@State isRefreshing: boolean = false;
@State isLoading: boolean = false;
@State hasMore: boolean = true;
private pageIndex: number = 1;
build() {
Column() {
Refresh({
refreshing: this.isRefreshing,
onRefresh: () => {
this.isRefreshing = true;
this.loadData(true);
}
}) {
List() {
ForEach(this.data, (item: Item) => {
ListItem() {
// 列表项UI
}
})
}
.onReachEnd(() => {
if (!this.isLoading && this.hasMore) {
this.isLoading = true;
this.loadData(false);
}
})
}
}
}
}
注意事项
- 确保在数据加载完成后更新
isRefreshing和isLoading状态 - 可根据需求添加加载中和无更多数据的UI提示
- 网络请求失败时需要正确处理状态重置
这种实现方式符合HarmonyOS Next的声明式UI范式,能流畅处理分页加载场景。

