HarmonyOS鸿蒙Next中List中的图片闪烁

HarmonyOS鸿蒙Next中List中的图片闪烁 LazyForEach渲染List,当更新数据源的时候列表中的图片会闪一下

4 回复

若仅靠LazyForEach的刷新机制,当item变化时若想更新子组件,需要将原来的子组件全部销毁再重新构建,在子组件结构较为复杂的情况下,靠改变键值去刷新渲染性能较低。因此框架提供了@Observed@ObjectLink机制进行深度观测,可以做到仅刷新使用了该属性的组件,提高渲染性能,避免更新listitem时图片闪烁问题

参考: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-rendering-control-lazyforeach-V5

改变数据子属性

可参考如下demo:

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

    })

  }

  notifyDataMove(from: number, to: number): void {

    this.listeners.forEach(listener => {

      listener.onDataMove(from, to);

    })

  }

}

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

  }

}

[@Observed](/user/Observed)

class StringData {

  message: string;

  constructor(message: string) {

    this.message = message;

  }

}

@Entry
@Component
struct MyComponent {

  private moved: number[] = [];

  @State data: MyDataSource = new MyDataSource();

  aboutToAppear() {

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

      this.data.pushData(new StringData(`Hello ${i}`));

    }

  }

  build() {

    List({ space: 3 }) {

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

        ListItem() {

          ChildComponent({data: item})

        }
        .onClick(() => {

          item.message += '0';

        })

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

    }.cachedCount(5)

  }

}

@Component
struct ChildComponent {

  [@ObjectLink](/user/ObjectLink) data: StringData

  build() {

    Row() {

      Image($r("app.media.startIcon"))
        .width(100)
        .height(100)

      Text(this.data.message).fontSize(50)
        .onAppear(() => {

          console.info("appear:" + this.data.message)

        })

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

  }

}

更多关于HarmonyOS鸿蒙Next中List中的图片闪烁的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


更新数据源没更换图片url 也闪了?是这个意思不?

如果是,LazyForEach 最后一个key 改一个跟UI无关的唯一id.

如果不是,那描述的清楚一点。比如是有一帧数的白屏,还是图片大小有变化导致布局有变动,还是单纯觉得图片变换不好看

在HarmonyOS鸿蒙Next中,List中的图片闪烁问题可能与以下因素有关:

  1. 数据绑定机制:鸿蒙的List组件使用数据绑定机制更新UI。如果数据频繁变化或绑定逻辑存在问题,可能导致图片频繁刷新,出现闪烁现象。

  2. 图片加载策略:图片加载时,如果未使用合适的缓存策略(如内存缓存或磁盘缓存),每次滚动时都会重新加载图片,导致闪烁。

  3. UI更新频率:List组件在滚动或数据更新时,如果UI刷新频率过高,可能会导致图片频繁重绘,引发闪烁。

  4. 硬件加速:鸿蒙系统支持硬件加速,但如果未正确配置或设备性能不足,可能导致渲染异常,出现图片闪烁。

  5. 布局优化:List组件的布局结构复杂或嵌套层级过深时,可能会影响渲染性能,导致图片闪烁。

  6. 代码实现:在自定义List组件或图片加载逻辑时,代码实现不当(如频繁调用invalidate()方法)也可能引发闪烁问题。

  7. 系统版本兼容性:鸿蒙Next版本可能存在特定问题或Bug,导致List中的图片闪烁。

  8. 资源占用:系统资源(如内存、CPU)不足时,可能导致UI渲染不稳定,出现图片闪烁。

以上是可能导致HarmonyOS鸿蒙Next中List中图片闪烁的原因,具体问题需结合代码和场景进一步分析。

在HarmonyOS鸿蒙Next中,List中的图片闪烁问题可能由以下原因引起:

  1. 图片加载性能问题:图片加载过程中未使用缓存或未优化加载逻辑,导致重复加载。建议使用Image组件时启用缓存,或使用第三方图片加载库如Glide进行优化。

  2. 布局更新频繁:List频繁刷新或布局重绘,导致图片闪烁。建议使用DiffUtil优化数据更新,减少不必要的布局刷新。

  3. UI线程阻塞:图片加载在主线程进行,导致UI卡顿。建议将图片加载放在异步线程,完成后更新UI。

  4. 硬件加速问题:检查是否启用了硬件加速,未启用可能导致渲染异常。可在AndroidManifest.xml中启用硬件加速。

通过优化图片加载、减少布局刷新和异步处理,可以有效解决图片闪烁问题。

回到顶部