HarmonyOS 鸿蒙Next中懒加载刷新UI
HarmonyOS 鸿蒙Next中懒加载刷新UI
初始列表有10条数据通过懒加载展示出来,当上拉到底部加载时接口会返回旧数据加新数据,为什么调用 listener.onDataReloaded()
列表页面不会实时刷新,但关闭列表页面然后重新打开就能看到新数据,该如何实现实时刷新
没有具体的实现代码嘛,根据你的描述,写了类似的demo,看下是否可以
// BasicDataSource实现了IDataSource接口,用于管理listener监听,以及通知LazyForEach数据更新
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];
public totalCount(): number {
return this.originDataArray.length;
}
public getData(index: number): string {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
});
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.ADD, index: index}]);
});
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.CHANGE, index: index}]);
});
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.DELETE, index: index}]);
});
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
// 写法2:listener.onDatasetChange(
// [{type: DataOperationType.EXCHANGE, index: {start: from, end: to}}]);
});
}
notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
});
}
}
class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
@Entry
@Component
struct PageDataReloaded {
private data: MyDataSource = new MyDataSource();
private isLoading = false
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(`Hello ${i}`);
}
}
build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Text(item)
.onAppear(() => {
console.info(`appear: ${item}`);
})
}
}
}, (item: string) => item)
}
.onReachEnd(() => {
this.isLoading = true
if (this.isLoading === true) {
for (let i = 0; i <= 20; i++) {
this.data.pushData(`Hello ${Math.random().toFixed(2)}`);
}
this.isLoading = false
}
})
}
}
更多关于HarmonyOS 鸿蒙Next中懒加载刷新UI的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
我的数据是接口下发的对象数组,不是字符串数组,
- 也可以使用@ohos/pulltorefresh:一款下拉刷新、上拉加载组件。支持设置内置动画的各种属性,支持设置自定义动画,支持lazyForEarch的数据作为数据源。
- 也可以参考下拉刷新和上拉加载效果自定义,https://developer.huawei.com/consumer/cn/doc/architecture-guides/custom_refresh-0000002331948181 3.修改对象数组定义接口就可以
interface ItemData {
id: string;
text: string;
}
数据定义部分string[],及返回值string部分定义为ItemData
private originDataArray: ItemData[] = [];
public getData(index: number): ItemData {
return this.originDataArray[index];
}
private dataArray: ItemData[] = [];
public getData(index: number): ItemData {
return this.dataArray[index];
}
public pushData(data: ItemData): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
let id = util.generateRandomUUID()
this.data.pushData({
id,
text: `Hello ${i}`
});
}
}
build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: ItemData) => {
ListItem() {
Row() {
Text(item.text)
.onAppear(() => {
console.info(`appear: ${item}`);
})
}
}
}, (item: ItemData) => JSON.stringify(item))
}
.onReachEnd(() => {
this.isLoading = true
if (this.isLoading === true) {
for (let i = 0; i <= 20; i++) {
let id = util.generateRandomUUID()
this.data.pushData({
id,
text: `Hello ${Math.random().toFixed(2)}`
});
}
this.isLoading = false
}
})
}
我一般使用三方库,实现上拉下拉刷新或加载更多数据
虽然不知道你的具体代码,但我建议早点更换成 Repeat 组件,我踩过坑
Repeat不支持V1装饰器… 没法换V2装饰器怎么办,
鸿蒙Next中懒加载刷新UI通过ArkUI的LazyForEach组件实现。该组件仅在列表项进入可视区域时动态创建组件,离开时销毁,优化内存使用。数据源需实现LazyDataSource接口,通过onDataReloaded()方法触发UI刷新。LazyForEach必须与List/Grid等滚动容器配合使用,数据变更时调用notifyDataChanged()通知更新。
在HarmonyOS Next中,listener.onDataReloaded()
方法可能未触发UI的即时重绘,原因通常是数据更新后未通知到UI组件进行刷新。建议使用 @State
或 @Link
装饰器管理列表数据,并在数据变更后调用 this.listData = [...newData]
或使用 splice
等方法更新数组引用,以触发组件重新渲染。确保数据源更新后UI层能接收到变更通知,避免依赖页面重建来显示新数据。