HarmonyOS 鸿蒙Next List lazyForeach List不能更新
HarmonyOS 鸿蒙Next List lazyForeach List不能更新
使用List 懒加载是初始化可以,但是更新数据UI不刷新。查看了指南
如上图,是必须要实现一个DataChangeListener ,然后registerDataChangeListener 才能更新List UI吗?
如果是这样,DataChangeListener 要怎么实现呢?
关于HarmonyOS 鸿蒙Next List lazyForeach List不能更新的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
希望HarmonyOS能继续加强在AI领域的研发,让系统更加智能化。
综上所述我猜测你可能出现问题的原因
LazyForEach(this.testList,(item:string,index:number) => {
ListItem(){
Row(){
Text(`第${index}项数据为:${item}`)
}.width(`100%`).height(`50`).onClick(() => {
this.testList[index] = "lalala"
})
}
})
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
你是直接修改了数据中某一项的值,此时修改的值并不会发生改变。如果想要实现点击后修改值然后列表更新需要在TestLazyDS中添加一个方法用于更改单独的一个item
public freshData(index:number,data: string):void{
this.dataArray[index] = data
this.notifyDataChange(index)
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
防止改变的值造成键值重复的问题最好在LazyForEach上添加键值处理,示例如下:
LazyForEach(this.testList,(item:string,index:number) => {
ListItem(){
Row(){
Text(`第${index}项数据为:${item}`)
}.width(`100%`).height(`50`).onClick(() => {
this.testList.freshData(index,(parseInt(item)+20).toString())
})
}
},(item:string,index:number) => item)
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
核心在两个,一个是更改数组后需要调用BasicDataSource中定义的onDataChange通知UI去更新列表,一个是
LazyForEach键值匿名函数keyGenerator重复造成的不刷新问题
参考文档:
感谢,确实是因为键值的问题,需要主动设置一个,保证更新之后,键值也会更新
string[]这种数组类型就能更新,但如果改成模型数组就不行了,就是我数组里面存放不是字符串,而是我自定义的模型,这样就没有办法更新了,请问如何解决
很喜欢HarmonyOS的卡片式设计,信息一目了然,操作也更便捷。
大佬问题解决了没有,我也是模型数据。更新不了视图
这个DataChangeListener不是你实现的,是在使用的时候运行环境来实现的,然后添加到你的IDataSource接口实现类的实例中,你要做的事情是数据变化之后,调用DataChangeListener的对应方法去通知数据发生了变化
官方文档:LazyForEach示例,其实就在你截图部分的下面,你的IDataSource实现类里面有registerDataChangeListener和unregisterDataChangeListener方法,你就当成是在运行过程中系统源码会来调用这2个方法,然后你在方法中保存传过来的DataChangeListener对象,数据有变化的时候(比如:MyDataSource对象向成员dataArray中push了一个数组成员,同时就调用一下notifyDataAdd方法,循环所有被register进来的listener,告知他们新增了一个数据
DataChangeListener类型说明
名称 | 描述 |
---|---|
onDataReloaded(): void | 重新加载所有数据。 |
onDataAdded(index: number): void (deprecated) | 通知组件index的位置有数据添加。 |
onDataMoved(from: number, to: number): void (deprecated) | 通知组件数据从from的位置移到to的位置。 |
onDataDeleted(index: number): void (deprecated) | 通知组件index的位置有数据删除。 |
onDataChanged(index: number): void (deprecated) | 通知组件index的位置有数据变化。 |
onDataAdd(index: number): void 8+ | 通知组件index的位置有数据添加。 |
onDataMove(from: number, to: number): void 8+ | 通知组件数据从from的位置移到to的位置。 |
onDataDelete(index: number): void 8+ | 通知组件index的位置有数据删除。 |
onDataChange(index: number): void 8+ | 通知组件index的位置有数据变化。 |
// xxx.ets
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = []
public totalCount(): number {
return 0
}
public getData(index: number): any {
return undefined
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener')
this.listeners.push(listener)
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener')
this.listeners.splice(pos, 1)
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded()
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index)
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index)
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index)
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to)
})
}
}
class MyDataSource extends BasicDataSource {
// 初始化数据列表
private dataArray: string[] = ['/path/image0.png', '/path/image1.png', '/path/image2.png', '/path/image3.png']
public totalCount(): number {
return this.dataArray.length
}
public getData(index: number): any {
return this.dataArray[index]
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data)
this.notifyDataAdd(index)
}
public pushData(data: string): void {
this.dataArray.push(data)
this.notifyDataAdd(this.dataArray.length - 1)
}
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct MyComponent {
private data: MyDataSource = new MyDataSource()
build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Image(item).width(50).height(50)
Text(item).fontSize(20).margin({ left: 10 })
}.margin({ left: 10, right: 10 })
}
.onClick(() => {
// 每点击一次列表项,数据增加一项
this.data.pushData('/path/image' + this.data.totalCount() + '.png')
})
}, item => item)
}
}
}
关于懒加载中有详细的代码示例,直接扒下来即可
参考文档:
interface IDataSource {
totalCount(): number; // 获得数据总数
getData(index: number): any; // 获取索引值对应的数据
registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器
unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}
interface DataChangeListener {
onDataReloaded(): void; // 重新加载数据时调用
onDataAdd(index: number): void; // 添加数据时调用
onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
onDataDelete(index: number): void; // 删除数据时调用
onDataChange(index: number): void; // 改变数据时调用
}
export class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): any {
return undefined;
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
this.listeners.splice(pos, 1);
}
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
import { BasicDataSource } from ‘./BasicDataSource’;
export class TestLazyDS extends BasicDataSource {
private dataArray = Array<string>();
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): any {
return this.dataArray[index];
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
public pushAllData(data: Array<string>): void {
this.dataArray.length = 0
this.dataArray.push(…data);
this.notifyDataReload();
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
我这里试,列表项数据增加没问题。但是更新已有到列表项数据不会刷新,调用了notifyDataChange 也不管用