HarmonyOS鸿蒙Next中List中的图片闪烁
HarmonyOS鸿蒙Next中List中的图片闪烁 LazyForEach渲染List,当更新数据源的时候列表中的图片会闪一下
若仅靠LazyForEach的刷新机制,当item变化时若想更新子组件,需要将原来的子组件全部销毁再重新构建,在子组件结构较为复杂的情况下,靠改变键值去刷新渲染性能较低。因此框架提供了@Observed与@ObjectLink机制进行深度观测,可以做到仅刷新使用了该属性的组件,提高渲染性能,避免更新listitem时图片闪烁问题
改变数据子属性
可参考如下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中的图片闪烁问题可能与以下因素有关:
-
数据绑定机制:鸿蒙的List组件使用数据绑定机制更新UI。如果数据频繁变化或绑定逻辑存在问题,可能导致图片频繁刷新,出现闪烁现象。
-
图片加载策略:图片加载时,如果未使用合适的缓存策略(如内存缓存或磁盘缓存),每次滚动时都会重新加载图片,导致闪烁。
-
UI更新频率:List组件在滚动或数据更新时,如果UI刷新频率过高,可能会导致图片频繁重绘,引发闪烁。
-
硬件加速:鸿蒙系统支持硬件加速,但如果未正确配置或设备性能不足,可能导致渲染异常,出现图片闪烁。
-
布局优化:List组件的布局结构复杂或嵌套层级过深时,可能会影响渲染性能,导致图片闪烁。
-
代码实现:在自定义List组件或图片加载逻辑时,代码实现不当(如频繁调用
invalidate()
方法)也可能引发闪烁问题。 -
系统版本兼容性:鸿蒙Next版本可能存在特定问题或Bug,导致List中的图片闪烁。
-
资源占用:系统资源(如内存、CPU)不足时,可能导致UI渲染不稳定,出现图片闪烁。
以上是可能导致HarmonyOS鸿蒙Next中List中图片闪烁的原因,具体问题需结合代码和场景进一步分析。
在HarmonyOS鸿蒙Next中,List中的图片闪烁问题可能由以下原因引起:
-
图片加载性能问题:图片加载过程中未使用缓存或未优化加载逻辑,导致重复加载。建议使用
Image
组件时启用缓存,或使用第三方图片加载库如Glide
进行优化。 -
布局更新频繁:List频繁刷新或布局重绘,导致图片闪烁。建议使用
DiffUtil
优化数据更新,减少不必要的布局刷新。 -
UI线程阻塞:图片加载在主线程进行,导致UI卡顿。建议将图片加载放在异步线程,完成后更新UI。
-
硬件加速问题:检查是否启用了硬件加速,未启用可能导致渲染异常。可在
AndroidManifest.xml
中启用硬件加速。
通过优化图片加载、减少布局刷新和异步处理,可以有效解决图片闪烁问题。