HarmonyOS 鸿蒙Next 网络请求数据源变更导致图片闪烁

HarmonyOS 鸿蒙Next 网络请求数据源变更导致图片闪烁

最外层组件A@Provide了一个全局的response, LazyForEach下一级组件; 类似A->B…->F 各级往下有各级的组件, B,C两层级组件都有各自的ForEach. F是那个checkbox, 点击后,会重新请求网络, 然后把自己@Consume的A的全局response给刷新了,接着从上到下全部刷新


更多关于HarmonyOS 鸿蒙Next 网络请求数据源变更导致图片闪烁的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

当数据源变化时,LazyForEach的刷新机制会导致整个ListItem被重建。由于Image组件是异步刷新,所以视觉上图片会发生闪烁。为了解决这种情况我们应该使用[@ObjectLink](/user/ObjectLink)和[@Observed](/user/Observed)去单独刷新数据源改变的listItem。

参考文档:

https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/quick-start/arkts-rendering-control-lazyforeach.md/#%E5%B8%B8%E8%A7%81%E4%BD%BF%E7%94%A8%E9%97%AE%E9%A2%98

class BasicDataSource implements IDataSource {

private listeners: DataChangeListener[] = [];

private originDataArray: StringData[] = [];

public totalCount(): number {

return 0;

}

public getData(index: number): StringData {

return this.originDataArray[index];

}

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);

})

}

}

class MyDataSource extends BasicDataSource {

private dataArray: StringData[] = [];

public totalCount(): number {

return this.dataArray.length;

}

public getData(index: number): StringData {

return this.dataArray[index];

}

public addData(index: number, data: StringData): void {

this.dataArray.splice(index, 0, data);

this.notifyDataAdd(index);

}

public pushData(data: StringData): void {

this.dataArray.push(data);

this.notifyDataAdd(this.dataArray.length - 1);

}

public reloadData(): void {

this.notifyDataReload();

}

}

class StringData {

message: string;

imgSrc: Resource;

constructor(message: string, imgSrc: Resource) {

this.message = message;

this.imgSrc = imgSrc;

}

}

@Entry

@Component

struct MyComponent {

private moved: number[] = [];

private data: MyDataSource = new MyDataSource();

aboutToAppear() {

for (let i = 0; i <= 20; i++) {

this.data.pushData(new StringData(Hello ${i}, $r(‘app.media.img’)));

}

}

build() {

List({ space: 3 }) {

LazyForEach(this.data, (item: StringData, index: number) => {

ListItem() {

Column() {

Text(item.message).fontSize(50)

.onAppear(() => {

console.info(“appear:” + item.message)

})

Image(item.imgSrc)

.width(500)

.height(200)

}.margin({ left: 10, right: 10 })

}

.onClick(() => {

item.message += ‘00’;

this.data.reloadData();

})

}, (item: StringData, index: number) => JSON.stringify(item))

}.cachedCount(5)

}

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

更多关于HarmonyOS 鸿蒙Next 网络请求数据源变更导致图片闪烁的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对HarmonyOS 鸿蒙Next网络请求数据源变更导致图片闪烁的问题,这通常是由于数据源变化引发组件重新渲染所致。具体可能的原因及解决方案如下:

  1. 数据源索引变化:若使用LazyForEach时依赖索引作为key,数据源变更(如排序、增减元素)会导致组件重建。建议改用数据项本身的唯一标识作为key,避免索引变化引起的重建。
  2. 数据源整体替换:每次数据变更都整体替换数据源,也会触发组件重建。应改为对数据源进行增量更新,如使用splice等方法修改数据,保持数据源引用不变。
  3. 图片加载问题:图片组件未使用缓存,每次加载都会重新请求。可在应用启动时设置图片缓存,提高加载效率,减少闪烁。

综上所述,通过优化LazyForEach的使用、精细化修改数据源以及启用图片缓存,可有效减少因数据源变更导致的图片闪烁问题。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部