HarmonyOS 鸿蒙Next List列表中的item宽高改变后造成了item重叠
目前通过List+LazyForEach的方式做了一个即时通讯的收发消息列表,其中用了ImageKnifeComponent来加载网络图片,当图片加载完成后修改List中item的宽高以保持图片原本的宽高比,但是改变宽高后会引起List中的item堆叠在一起,请问应该怎么解决?
目前在图像加载完成后调用this.dataSource.notifyDataChange(index)仍然无法解决问题。
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.imageUrl,
placeholderSrc: $r("app.media.im_pic_msg_holder"),
errorholderSrc: $r("app.media.im_pic_msg_holder"),
objectFit: ImageFit.Auto,
border: { radius: 5 },
onLoadListener: {
onLoadSuccess: (data: PixelMap) => {
data.getImageInfo().then((value: image.ImageInfo) => {
if (value.size.width > value.size.height && value.size.width > 160) {
let scale: number = 160 / value.size.width;
this.imageWidth = 160;
this.imageHeight = value.size.height * scale;
} else if (value.size.width > value.size.height && value.size.width <= 160) {
this.imageWidth = value.size.width;
this.imageHeight = value.size.height;
} else if (value.size.width < value.size.height && value.size.height > 130) {
let scale: number = 130 / value.size.height;
this.imageWidth = scale * value.size.width;
this.imageHeight = 130;
} else if (value.size.width < value.size.height && value.size.height <= 130) {
this.imageWidth = value.size.width;
this.imageHeight = value.size.height;
}
let eventData: emitter.EventData = {
data: { 'index': this.index }
}
emitter.emit(EventUtils.getInstance().eventImgLoaded,eventData)
})
}
}
}
}).width(this.imageWidth).height(this.imageHeight)
更多关于HarmonyOS 鸿蒙Next List列表中的item宽高改变后造成了item重叠的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以在循环中添加 keyGenerator 。
import {ImageKnifeComponent , RequestOption,
ImageKnifeData,
ImageKnife,
ImageKnifeGlobal} from '@ohos/imageknife'
import { BusinessError } from '@kit.BasicServicesKit';
import LazyDataSource from './LazyDataSource';
@Component
struct MessageViewItem {
@ObjectLink item: MOAMessageModel;
aboutToAppear(): void {
let imageKnifeOption: RequestOption = new RequestOption();
imageKnifeOption.load(this.item.imageUrl)
.addListener({callback:(err:BusinessError|string, data:ImageKnifeData) => {
if (data.isPixelMap()) {
console.log("TEST== data: " + JSON.stringify(data))
if (data.drawPixelMap) {
let pixelmap = data.drawPixelMap.imagePixelMap;
if (pixelmap) {
console.log("TEST== pixelmap: " + JSON.stringify(pixelmap))
pixelmap.getImageInfo((error, imageInfo) => {
if(error) {
console.log("");
} else {
let value = imageInfo
if (value.size.width > value.size.height && value.size.width > 160) {
let scale: number = 160 / value.size.width;
this.item.imageWidth = 160;
this.item.imageHeight = value.size.height * scale;
} else if (value.size.width > value.size.height && value.size.width <= 160) {
this.item.imageWidth = value.size.width;
this.item.imageHeight = value.size.height;
} else if (value.size.width < value.size.height && value.size.height > 160) {
let scale: number = 160 / value.size.height;
this.item.imageWidth = scale * value.size.width;
this.item.imageHeight = 160;
} else if (value.size.width < value.size.height && value.size.height <= 160) {
this.item.imageWidth = value.size.width;
this.item.imageHeight = value.size.height;
}
this.item.imgResized = true;
}
})
}
}
}
return false;
}})
let imageKnife:ImageKnife|undefined = ImageKnifeGlobal.getInstance().getImageKnife();
if(imageKnife != undefined){
imageKnife.call(imageKnifeOption)
}
}
build() {
Column() {
Text("测试")
.fontSize(18)
.backgroundColor(Color.Red)
ImageKnifeComponent({
imageKnifeOption: {
loadSrc: this.item.imageUrl,
}
}).width(this.item.imageWidth).height(this.item.imageHeight)
.backgroundColor(Color.Red)
}
.margin({
top:20
})
}
}
@Observed
export class MOAMessageModel{
imageHeight: number = 160;
imageWidth: number = 160;
imageUrl: string = "";
imgResized: boolean = false;
constructor(imageHeight_:number,imageWidth_:number,imageUrl_:string,imgResized_:boolean) {
this.imageHeight = imageHeight_
this.imageWidth = imageWidth_
this.imageUrl = imageUrl_
this.imgResized = imgResized_
}
}
@Entry
@Component
struct Index {
private dataSource: LazyDataSource<MOAMessageModel> = new LazyDataSource();
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.dataSource.pushData( new MOAMessageModel(15,15,"xxx",false))
}
}
build() {
Column(){
//聊天消息列表
List() {
LazyForEach(this.dataSource, (item: MOAMessageModel, index: number) => {
ListItem() {
MessageViewItem({
item: item,
})
}
}, (item: MOAMessageModel, index: number) => (item.imageWidth.toString() + item.imageHeight.toString() + index.toString()))
}
.edgeEffect(EdgeEffect.None)
.layoutWeight(1)
.padding({ bottom: 10 })
}
}
}
import { ObservedArray } from './ObservedArray';
class BasicDataSource <T> implements IDataSource {
private listeners: DataChangeListener[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): T | undefined {
return undefined;
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
}
@Observed
export default class LazyDataSource<T> extends BasicDataSource<T> {
dataArray: T[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): T {
return this.dataArray[index];
}
public addData(index: number, data: T): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: T): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
public pushArrayData(newData: ObservedArray<T>): void {
this.clear();
this.dataArray.push(...newData);
this.notifyDataReload();
}
public appendArrayData(addData: ObservedArray<T>): void {
this.dataArray.push(...addData);
this.notifyDataReload()
}
public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}
public getDataList(): ObservedArray<T> {
return this.dataArray;
}
public clear(): void {
this.dataArray.splice(0, this.dataArray?.length)
}
public isEmpty(): boolean {
return this.dataArray.length === 0;
}
}
@Observed
export class ObservedArray<T> extends Array<T> {
constructor(args?: T[]) {
if (args instanceof Array) {
super(...args);
} else {
super();
}
}
}
更多关于HarmonyOS 鸿蒙Next List列表中的item宽高改变后造成了item重叠的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中,Next List列表的item宽高改变后造成重叠的问题,通常是由于布局管理未正确响应尺寸变化所导致的。以下是可能的原因及直接解决方法:
-
布局容器属性:检查item的布局容器(如DirectionalLayout, GridLayout等)是否设置了正确的对齐和填充属性。确保在调整item尺寸时,容器能够自动调整以容纳新的尺寸。
-
Item的Margin和Padding:确认item的内外边距(margin和padding)设置是否合理,避免由于边距重叠导致的视觉问题。
-
布局约束:使用布局约束(如constraint layout)时,确保所有约束条件正确无误,并且能够在item尺寸变化时保持预期的布局效果。
-
动画与过渡效果:如果item的尺寸变化伴随动画或过渡效果,检查这些效果是否可能干扰了布局的重绘过程。
-
组件刷新:在动态修改item尺寸后,确保调用了适当的刷新或重绘方法,如invalidate()或requestLayout(),以通知系统重新计算布局。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html