HarmonyOS鸿蒙Next中如何使用Refresh组件实现列表的下拉刷新功能?
HarmonyOS鸿蒙Next中如何使用Refresh组件实现列表的下拉刷新功能? 我想为列表添加下拉刷新功能,想了解:
- Refresh 组件如何包裹 List 实现下拉刷新?
- onRefreshing 回调如何处理刷新逻辑?
- refreshing 属性如何控制刷新状态的显示和隐藏?
- 如何自定义下拉刷新的 UI 样式?
- 如何实现下拉刷新 + 上拉加载更多的组合功能?
希望能获取下拉刷新的完整实现代码。
实现思路:
- 使用 Refresh 组件包裹 List,通过 refreshing 属性控制刷新状态:
@State isRefreshing: boolean = false;
Refresh({ refreshing: $$this.isRefreshing }) {
List() {
// 列表内容
}
}
- 在 onRefreshing 回调中处理刷新逻辑,完成后设置 refreshing 为 false:
.onRefreshing(async () => {
await this.refreshData();
this.isRefreshing = false;
})
- 结合 onReachEnd 实现上拉加载更多:
List()
.onReachEnd(() => {
this.loadMore();
})
- 完整示例代码:
@Entry
@Component
struct RefreshExample {
@State dataList: DataItem[] = [];
@State isRefreshing: boolean = false;
@State isLoadingMore: boolean = false;
@State hasMore: boolean = true;
private page: number = 1;
async aboutToAppear() {
await this.loadData();
}
async loadData(): Promise<void> {
this.page = 1;
this.dataList = await this.fetchData(this.page);
this.hasMore = true;
}
async refreshData(): Promise<void> {
this.page = 1;
this.dataList = await this.fetchData(this.page);
this.hasMore = true;
}
async loadMore(): Promise<void> {
if (this.isLoadingMore || !this.hasMore) return;
this.isLoadingMore = true;
this.page++;
const newData = await this.fetchData(this.page);
if (newData.length === 0) {
this.hasMore = false;
} else {
this.dataList = [...this.dataList, ...newData];
}
this.isLoadingMore = false;
}
async fetchData(page: number): Promise<DataItem[]> {
return new Promise((resolve) => {
setTimeout(() => {
const items: DataItem[] = [];
for (let i = 0; i < 10; i++) {
items.push({
id: `${page}-${i}`,
name: `Item ${(page - 1) * 10 + i + 1}`
});
}
resolve(items);
}, 1000);
});
}
build() {
Column() {
Refresh({ refreshing: $$this.isRefreshing }) {
List({ space: 8 }) {
ForEach(this.dataList, (item: DataItem) => {
ListItem() {
Text(item.name)
.width('100%')
.padding(16)
.backgroundColor('#FFF')
.borderRadius(8)
}
}, (item: DataItem) => item.id)
// 加载更多
ListItem() {
Row() {
if (this.isLoadingMore) {
LoadingProgress().width(20).height(20)
Text('加载中...').margin({ left: 8 })
} else if (!this.hasMore) {
Text('没有更多了').fontColor('#999')
}
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.height('100%')
.padding(16)
.onReachEnd(() => this.loadMore())
}
.onRefreshing(async () => {
await this.refreshData();
this.isRefreshing = false;
})
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
interface DataItem {
id: string;
name: string;
}
更多关于HarmonyOS鸿蒙Next中如何使用Refresh组件实现列表的下拉刷新功能?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用Refresh组件实现列表下拉刷新功能,需在ArkUI中通过@State装饰器管理刷新状态。将Refresh组件作为父容器包裹List组件,通过onRefresh回调触发数据刷新操作,并在异步数据加载完成后调用finishRefresh方法结束刷新状态。
在HarmonyOS Next中,使用Refresh组件实现列表下拉刷新功能,核心是将其作为List的父容器。以下是针对你问题的具体实现方案和代码示例。
1. Refresh 包裹 List 的基本结构
Refresh组件通过refreshing属性控制刷新状态,并使用onRefresh回调(对应你提到的onRefreshing)触发数据加载。基本结构如下:
import { Refresh, List, ListItem } from '@kit.ArkUI';
@Entry
@Component
struct RefreshExample {
@State isRefreshing: boolean = false; // 控制刷新状态
private data: string[] = ['Item 1', 'Item 2', 'Item 3']; // 示例数据
build() {
Refresh({
refreshing: this.isRefreshing,
onRefresh: () => {
this.isRefreshing = true;
// 模拟数据加载,2秒后结束刷新
setTimeout(() => {
this.data.unshift('New Item'); // 添加新数据
this.isRefreshing = false;
}, 2000);
}
}) {
List() {
ForEach(this.data, (item: string) => {
ListItem() {
Text(item).fontSize(20).margin(10)
}
})
}
}
}
}
2. onRefreshing 回调处理逻辑
onRefresh回调在用户下拉时触发,通常在此处执行网络请求或本地数据加载。示例中通过setTimeout模拟异步操作,实际开发需替换为具体数据逻辑(如fetch请求)。刷新完成后,必须将refreshing设为false以隐藏加载指示器。
3. refreshing 属性控制状态
refreshing: true:显示加载指示器,禁用下拉操作。refreshing: false:隐藏指示器,恢复下拉功能。 通过@State变量动态绑定此属性,即可实现状态同步。
4. 自定义下拉刷新 UI
Refresh组件支持通过builder属性完全自定义下拉区域样式。例如,替换默认指示器为文字和图标:
Refresh({
refreshing: this.isRefreshing,
onRefresh: () => { /* 刷新逻辑 */ },
builder: (refreshState: RefreshStatus) => {
// 根据状态显示不同内容
if (refreshState === RefreshStatus.Inactive) {
return Text('下拉刷新').fontColor('#666');
} else if (refreshState === RefreshStatus.Drag) {
return Text('释放刷新').fontColor('#007DFF');
} else {
return Row() {
LoadingProgress().width(20).height(20);
Text('加载中...').margin({ left: 10 });
};
}
}
}) {
List() { /* 列表内容 */ }
}
RefreshStatus枚举提供Inactive(未激活)、Drag(下拉中)、Refresh(刷新中)等状态,可用于精细化UI控制。
5. 下拉刷新 + 上拉加载更多
需结合Refresh和List的onReachEnd回调实现。示例:
@State isRefreshing: boolean = false;
@State isLoadingMore: boolean = false;
private data: string[] = [...];
private page: number = 1;
build() {
Refresh({
refreshing: this.isRefreshing,
onRefresh: () => {
this.isRefreshing = true;
// 下拉刷新:重置数据
this.page = 1;
this.loadData(true);
}
}) {
List({ space: 10 }) {
ForEach(this.data, (item) => {
ListItem() { Text(item) }
})
// 上拉加载更多提示
if (this.isLoadingMore) {
ListItem() {
Row() {
LoadingProgress();
Text('加载更多...').margin({ left: 10 });
}.justifyContent(FlexAlign.Center).width('100%').padding(20)
}
}
}
.onReachEnd(() => {
// 触发上拉加载
if (!this.isLoadingMore) {
this.isLoadingMore = true;
this.page += 1;
this.loadData(false);
}
})
}
}
// 统一数据加载函数
loadData(isRefresh: boolean) {
// 模拟网络请求
setTimeout(() => {
const newData = [`Page ${this.page} Item`];
if (isRefresh) {
this.data = newData; // 刷新时替换数据
} else {
this.data.push(...newData); // 加载更多时追加数据
}
this.isRefreshing = false;
this.isLoadingMore = false;
}, 1500);
}
关键点:
- 下拉刷新由
Refresh的onRefresh处理,通常重置页码并更新数据。 - 上拉加载通过
List的onReachEnd触发,需防止重复请求(示例中用isLoadingMore状态锁)。 - 列表底部通过条件渲染显示加载提示。
完整示例代码
以下为整合下拉刷新、上拉加载及自定义UI的完整代码:
import { Refresh, List, ListItem, LoadingProgress, RefreshStatus } from '@kit.ArkUI';
@Entry
@Component
struct FullRefreshExample {
@State isRefreshing: boolean = false;
@State isLoadingMore: boolean = false;
@State data: string[] = ['初始数据1', '初始数据2', '初始数据3'];
private page: number = 1;
build() {
Refresh({
refreshing: this.isRefreshing,
onRefresh: () => {
this.isRefreshing = true;
this.page = 1;
this.loadData(true);
},
builder: (refreshState: RefreshStatus) => {
// 自定义下拉区域
return Column() {
if (refreshState === RefreshStatus.Refresh) {
LoadingProgress().width(30).height(30);
Text('拼命加载中...').fontSize(14).margin({ top: 8 });
} else {
Image($r('app.media.arrow_down'))
.width(25)
.rotate({ angle: refreshState === RefreshStatus.Drag ? 180 : 0 });
Text(refreshState === RefreshStatus.Drag ? '释放刷新' : '下拉刷新')
.fontSize(14)
.margin({ top: 8 });
}
}.padding(15);
}
}) {
List({ space: 5 }) {
ForEach(this.data, (item: string, index?: number) => {
ListItem() {
Text(`${index + 1}. ${item}`)
.fontSize(18)
.padding(15)
.backgroundColor('#FFF')
.width('100%')
}
})
// 上拉加载更多区域
if (this.isLoadingMore) {
ListItem() {
Row() {
LoadingProgress().width(20).height(20);
Text('加载更多数据...').margin({ left: 10 });
}
.justifyContent(FlexAlign.Center)
.width('100%')
.padding(20)
}
}
}
.onReachEnd(() => {
if (!this.isLoadingMore) {
this.isLoadingMore = true;
this.page += 1;
this.loadData(false);
}
})
.width('100%')
.backgroundColor('#F1F1F1')
}
}
loadData(isRefresh: boolean) {
// 模拟异步请求
setTimeout(() => {
const newData = Array.from({ length: 3 }, (_, i) =>
`第${this.page}页数据${i + 1}`
);
if (isRefresh) {
this.data = newData;
} else {
this.data = [...this.data, ...newData];
}
this.isRefreshing = false;
this.isLoadingMore = false;
}, 2000);
}
}
注意事项
- 确保
refreshing状态在数据加载完成后及时更新,避免界面卡死。 - 上拉加载时建议添加数据为空或加载失败的占位提示。
- 自定义
builder时,可通过RefreshStatus枚举值适配不同状态下的UI表现。
以上代码可直接运行测试,根据实际需求调整数据加载逻辑和样式即可。

