赞
踩
鸿蒙提供了两种列表渲染模式,一种是ForEach,另外一种是LazyForEach-官方文档
LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。
LazyForEach的使用特别像之前前端领域里的一个叫做虚拟列表的概念, 不论你有100条还是100000条记录,当前始终只渲染可视区域的内容,也就是5条,10条,只不过原来我们需要借助不同的虚拟列表组件或者自己去实现,这里面我们直接使用LazyForEach就可以了,但是同样的,使用LazyForEach遍历的数据源必须继承实现IDataSource这个接口
也就是我们的数据源不能再使用原始的数组对象,数据源必须实现IDataSource里面的几个方法
在models下新建一个base_datasource.ets
export class BasicDataSource implements IDataSource { private listeners: DataChangeListener[] = []; public totalCount(): number { return 0; } public getData(index: number): object | null { return null ; } // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听 registerDataChangeListener(listener: DataChangeListener): void { if (this.listeners.indexOf(listener) < 0) { console.info('add listener'); this.listeners.push(listener); } } // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听 unregisterDataChangeListener(listener: DataChangeListener): void { const pos = this.listeners.indexOf(listener); if (pos >= 0) { console.info('remove listener'); 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); }) } } export class ListDataSource extends BasicDataSource { private dataArray: object[] = []; public totalCount(): number { return this.dataArray.length; } public getData(index: number): object { return this.dataArray[index]; } public addData(index: number, data: object): void { this.dataArray.splice(index, 0, data); this.notifyDataAdd(index); } public pushData(data: object): void { this.dataArray.push(data); this.notifyDataAdd(this.dataArray.length - 1); } public reloadData (list: object[]) { this.dataArray = list this.notifyDataReload() // 重新加载 } }
export * from './base_datasource'
import { HmLoading } from './HmLoading' import { ListDataSource } from '../models' @Component struct HmList { @State refreshIng: boolean = false // 控制下拉刷新 @State loading: boolean = false // 控制上拉加载 @Prop finished: boolean // 是否结束 @Link @Watch("updateDataSource") dataSource: object[] // 数据源 @BuilderParam renderItem: (item: object) => void onLoad: () => void = () => { } // 上拉加载函数 onRefresh: () => void = () => { } // 下拉刷新函数 loadingText: string = "加载数据中" // 加载中文本 finishText: string = "没有内容啦" // 结束文本 showLoadingIcon: boolean = true // 是否显示加载进度 lazyDataSource: ListDataSource = new ListDataSource() // 更新数据 updateDataSource() { this.lazyDataSource.reloadData(this.dataSource) } // 获取底部显示的文本 @Builder getBottomDisplay() { Row({ space: 10 }) { if (this.finished) { Text(this.finishText) .fontSize(14) .fontColor($r("app.color.text_secondary")) } else { if (this.loading) { Text(this.loadingText) .fontSize(14) .fontColor($r("app.color.text_secondary")) if(this.showLoadingIcon) { HmLoading({ hWidth: 20 }) } } } } .height(50) .width('100%') .justifyContent(FlexAlign.Center) } build() { Refresh({ refreshing: $$this.refreshIng }) { List() { LazyForEach(this.lazyDataSource, (item: object) => { ListItem() { if (this.renderItem) { this.renderItem(item) } }.width('100%') }) ListItem() { this.getBottomDisplay() } } .onReachEnd(async () => { if (!this.finished && !this.loading) { this.loading = true await this.onLoad() this.loading = false } }) } .onStateChange(async value => { if (value === RefreshStatus.Refresh) { await this.onRefresh() this.refreshIng = false this.loading = false } }) } } export { HmList }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。