HarmonyOS鸿蒙Next中数组改变foreach渲染图片出现闪烁
HarmonyOS鸿蒙Next中数组改变foreach渲染图片出现闪烁
目前有一个数组A其中包含了数组B(数组A的属性)
-
使用数组A遍历三个按钮
-
使用数组B去渲染图片
-
当点击A渲染的按钮时获取index,根据index去切换数组B
~~ ForEach(this.cardListArr[this.SelectIndex].couponInfoVoList,()=>{})
当我们切换时数组B所渲染的图片出现闪烁
可使用图片的syncLoad方法,参考地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-image-V5#syncload8
interface FirstArrInterface {
NameAndId: string
SecondArr: Array<SecondArrInterface>
}
class SecondArrInterface {
NameAndId: string = ""
Num: number = 0
Desc: string = ""
}
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: SecondArrInterface[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): SecondArrInterface {
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: SecondArrInterface[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): SecondArrInterface{
return this.dataArray[index];
}
public addData(index: number, data: SecondArrInterface): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: SecondArrInterface): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
@Component
struct Index {
@State FirstArr: Array<FirstArrInterface> = []
@State SecondArr: Array<SecondArrInterface> = []
@State SelectIndex: number = 0
@State data: MyDataSource = new MyDataSource();
initData() {
this.FirstArr = [
{
NameAndId: "FirstArr1",
SecondArr: [
{
NameAndId: "SecondArr1",
Num: 1,
Desc: "SecondArr1",
},
{
NameAndId: "SecondArr1.2",
Num: 1.2,
Desc: "SecondArr1.2",
}
]
},
{
NameAndId: "FirstArr2",
SecondArr: [{
NameAndId: "SecondArr2",
Num: 2,
Desc: "SecondArr2",
}, {
NameAndId: "SecondArr2.2",
Num: 2.2,
Desc: "SecondArr2.2",
}]
},
{
NameAndId: "FirstArr3",
SecondArr: [{
NameAndId: "SecondArr3",
Num: 3,
Desc: "SecondArr3",
}]
},
]
this.SecondArr = this.FirstArr[this.SelectIndex].SecondArr
}
initData2() {
this.SecondArr = this.FirstArr[this.SelectIndex].SecondArr
}
onPageShow(): void {
this.initData()
}
build() {
Column({ space: 14 }) {
Row() {
ForEach(this.FirstArr, (item: FirstArrInterface, index: number) => {
Button(item.NameAndId).onClick(() => {
this.SelectIndex = index
this.initData2()
})
}, (item: FirstArrInterface) => item.NameAndId)
}
.justifyContent(FlexAlign.SpaceAround)
.margin({
top: 20
})
.padding({
top: 15,
bottom: 15,
})
.backgroundColor("#cecece")
.width("100%")
Row() {
ForEach(this.SecondArr, (item: SecondArrInterface) => {
itemView({item: item})
}, (item: SecondArrInterface) => item.NameAndId)
}
.padding({
top:10,
bottom:10
})
.justifyContent(FlexAlign.SpaceBetween)
.width("100%")
.backgroundColor("#993366")
}
.height('100%')
.width('100%')
}
}
@Component
struct itemView {
@ObjectLink item:SecondArrInterface
build() {
Column() {
Text(this.item.Desc)
.position({
top: 12,
left: 12
})
.zIndex(2)
Text(this.item.Num + "")
.position({
top: 12,
right: 12
})
.zIndex(2)
Image($r("app.media.ceshi"))
.width("167")
.height("67")
.syncLoad(true)
}
.width("167")
.height("67")
}
}
更多关于HarmonyOS鸿蒙Next中数组改变foreach渲染图片出现闪烁的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
syncLoad,我试了下,滑动卡顿了都,这个方法还是不行,
你是在模拟器还是真机上运行的,syncload在传true的话有缓存的情况下不闪的,
如果syncload不可行,给图片设置下缓存
onPageShow() {
// 设置解码前图片数据内存缓存上限为100MB (100MB=100*1024*1024B=104857600B)
app.setImageRawDataCacheSize(104857600)
console.info('Application onPageShow')
}
在HarmonyOS鸿蒙Next中,数组改变时使用foreach渲染图片出现闪烁,通常是由于UI刷新机制引起的。HarmonyOS的UI框架在数组数据发生变化时,会重新渲染相关的UI组件。如果数组频繁变化,且foreach中的图片组件没有正确处理数据变更,可能会导致图片闪烁。
解决方法可以通过以下方式优化:
-
使用
@State或@Link绑定数据:确保数组数据的变化能够正确触发UI更新,避免不必要的重新渲染。@State用于组件内部状态管理,@Link用于父子组件间的状态同步。 -
优化
foreach中的组件:在foreach中渲染图片时,确保每个图片组件都有唯一的key属性。这样可以避免框架误判组件的变化,减少不必要的重新渲染。 -
使用
LazyForEach代替foreach:LazyForEach是鸿蒙提供的优化列表渲染的组件,它可以延迟加载和销毁不在可视区域的组件,减少性能开销和渲染闪烁。 -
图片缓存:使用鸿蒙提供的图片缓存机制,避免重复加载图片资源。可以通过
Image组件的cached属性或使用ImageCache进行图片缓存管理。 -
减少数据变更频率:如果数组变化频繁,可以考虑合并多次数据变更,减少UI刷新的次数。
通过这些优化手段,可以有效减少数组改变时foreach渲染图片出现的闪烁问题。


