鸿蒙6.0开发常见问题【双层嵌套list,如何使用LazyForEach起作用?】
·
问题场景
在外层ListA中,每个ListItem包含一个内层List,内层List使用LazyForEach实现懒加载效果。如果为外层ListA的每个ListItem设置高度,内层List的LazyForEach会失效,所有项会一次性加载。如果不设置外层ListA的每个ListItem的高度,内层List的LazyForEach会正常工作,但部分内层List的数据可能显示不完全。
解决措施
固定内层List高度。参考如下代码
export class BaseDataSource<T> implements IDataSource {
private readonly listeners: DataChangeListener[] = [];
protected dataset: T[];
constructor(dataset?: T[]) {
this.dataset = dataset ?? [];
}
public resetDataset(dataset: T[]) {
this.dataset = dataset;
this.notifyDataReload();
}
public updateDataAt(index: number, data: T) {
if (index >= 0 && index < this.dataset.length) {
this.dataset[index] = data;
this.notifyDataChange(index);
}
}
public getDataset() {
return this.dataset;
}
public totalCount(): number {
return this.dataset.length;
}
public getData(index: number): T {
return this.dataset[index];
}
/**
* Notify LazyForEach component to reload all child components
*/
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
/**
* Notify LazyForEach component to add a sub component at the index corresponding to the index
* @param index
*/
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
/**
* Notify LazyForEach component that there is a change in data at the index corresponding to the index, and that the sub component needs to be rebuilt
* @param index
*/
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
/**
* Notify LazyForEach component to remove the sub component at the index corresponding to the index
* @param index
*/
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
/**
* Notify LazyForEach component to swap the subcomponents at the from index and to index
* @param from
* @param to
*/
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
//----------------------------------------------------------------------------------------------------
// This method is called on the framework side to add listener listening to the LazyForEach component at its data source
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
// This method is called on the framework side to remove listener listening for the corresponding LazyForEach component at the data source
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
this.listeners.splice(pos, 1);
}
}
}
class NewPosItemDataSource extends BaseDataSource<string> {
private dataArray: string[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
const bgColors: ResourceColor[] = [Color.Blue, Color.Gray];
const rowHeight = 60;
@Component
struct header {
title: string = '';
build() {
Column() {
Text(this.title)
.width('100%')
.height(40)
.fontSize(14)
.backgroundColor(Color.Yellow)
.fontColor(Color.Blue)
.textAlign(TextAlign.Center)
}
}
}
@Component
struct Itemcomponent {
title: string = '';
@Prop datas: string[];
generateDataSource() {
let datasource: NewPosItemDataSource = new NewPosItemDataSource();
for (let index = 0; index < this.datas.length; index++) {
const element = this.datas[index];
datasource.pushData(element);
}
return datasource;
}
build() {
Column() {
header({ title: this.title })
List() {
LazyForEach(this.generateDataSource(), (data: string, index) => {
ListItem() {
Text(data)
.width('100%')
.fontSize(14)
.backgroundColor(Color.White)
.fontColor(bgColors[index % bgColors.length])
.textAlign(TextAlign.Center)
}
.height(rowHeight)
}, (data: string, index) => {
console.log(`------- ${data + ' - ' + index.toString()}`);
return data + ' - ' + index.toString();
})
}
.layoutWeight(1)
.scrollBar(BarState.Off)
.cachedCount(10)
.friction(1.25)
.edgeEffect(EdgeEffect.None)
}
}
}
function generateData(pre: string, count: number) {
let datas: string[] = [];
for (let index = 0; index < count; index++) {
const element = pre + '-' + index.toString();
datas.push(element);
}
return datas;
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
private scroll: Scroller = new Scroller();
@Builder
private mainListView() {
List({ scroller: this.scroll }) {
ListItem() {
Itemcomponent({ title: 'A', datas: generateData('A', 200) })
}
// .height(40 + 200 * rowHeight) // After adding the height attribute, the content area of the inner list will be as high as the visible area, causing LazyForEach to become invalid
ListItem() {
Itemcomponent({ title: 'B', datas: generateData('B', 20) })
}
// .height(40 + 20 * rowHeight) // After adding the height attribute, the content area of the inner list will be as high as the visible area, causing LazyForEach to become invalid
}
.divider({ strokeWidth: 10, color: Color.Gray })
.height("100%")
.width("100%")
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
}
build() {
Column() {
this.mainListView()
}.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
}
更多推荐



所有评论(0)