HarmonyOS 鸿蒙分组列表的高效懒加载实现

发布于 1周前 作者 yuanlaile 来自 鸿蒙OS

HarmonyOS 鸿蒙分组列表的高效懒加载实现
<markdown _ngcontent-brp-c237="" class="markdownPreContainer">

双重嵌套列表,两个列表都实现懒加载效果

效果图如下:

实现的主逻辑如下:

  1. 日期header使用一个DataSource
  2. 使用一个map保存每个日期里面新闻列表的DataSource
[@Component](/user/Component)
export default struct FlashNewsTab {
  // 外部LazyForEach的DataSource
  private ds: LazyDataSource<FlashNewsModelWithTitle> = new LazyDataSource<FlashNewsModelWithTitle>();
  // 内部LazyForEach的DataSource,使用title作为key,创建一个Map
  private dsInners: HashMap<string, LazyDataSource<FlashNewsModel>> = new HashMap<string, LazyDataSource<FlashNewsModel>>();
  private vm: FlashNewsTabViewModel = new FlashNewsTabViewModel();

aboutToAppear(): void { // 初始化DataSource let flashNews: FlashNewsModelWithTitle[] = this.vm.requestFlashNews() this.ds.initData(flashNews) flashNews.forEach((it) => { let dsInner: LazyDataSource<FlashNewsModel> = new LazyDataSource<FlashNewsModel>(); dsInner.initData(it.flashNews) this.dsInners.set(it.title, dsInner) }) }

build() { Column() { List({ space: 8 }) { // 双层LazyForEach循环 LazyForEach(this.ds, (it: FlashNewsModelWithTitle) => { ListItemGroup({ header: this.ItemHeader(it.title), space: 8 }) { // 根据Title获取DataSource LazyForEach(this.dsInners.get(it.title), (it: FlashNewsModel) => { ListItem() { ItemFlashNews({ m: it }) } }, (it: FlashNewsModel) => it.id.toString()) } }, (it: FlashNewsModelWithTitle) => it.title.toString()) } .fullWidth() .layoutWeight(1) .contentEndOffset(12) .scrollBar(BarState.Off) .sticky(StickyStyle.Header) .cachedCount(3) } .fullWidth() .height(‘100%’) .padding(horizontal(12)) } } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>

源码地址见码云:源码下载

</markdown>

关于HarmonyOS 鸿蒙分组列表的高效懒加载实现的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
4 回复
请问这样子列表可以更新吗?比如说选中或者删除某个子列表的item

可以呀,选中跟平常的lazyforeach没有区别,可以通过@Observed@ObjectLink来做更新。 删除的话可以通过拿到所属的datasource来自操作

大佬牛逼,我验证一下

如果需要做选中的功能:可以通过[@Observed](/user/Observed) 和[@ObjectLink](/user/ObjectLink)来做更新。

1,model添加Observed

// 添加一个observed注解
[@Observed](/user/Observed)
export default class FlashNewsModel {
  id: number;
  time: string;
  day: string;
  content: string;
  // 添加一个属性
  checked: boolean;

constructor( id: number, time: string, day: string, content: string, checked: boolean = false ) { this.id = id; this.time = time; this.day = day; this.content = content; this.checked = checked; } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

2,子组件添加ObjectLink注解

@Component
export default struct ItemFlashNews {
// 将Prop更改为 ObjectLink
@ObjectLink m: FlashNewsModel
@State lineHeight: Length = 1

build() { Row({ space: 6 }) { Column() { Circle() .fillOpacity(0) .stroke($r(‘app.color.primary_blue’)) .strokeWidth(2) .width(9) .height(9) .margin({ top: 4.5 }) Stack() .backgroundColor($r(‘app.color.list_divider’)) .width(1) .height(this.lineHeight)

  }.width(<span class="hljs-number"><span class="hljs-number">9</span></span>)

  Checkbox().width(<span class="hljs-number"><span class="hljs-number">24</span></span>).height(<span class="hljs-number"><span class="hljs-number">24</span></span>)
    .select(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.m.checked)
}
.fullWidth()
.padding({
  top: <span class="hljs-number"><span class="hljs-number">12</span></span>,
  left: <span class="hljs-number"><span class="hljs-number">6</span></span>,
  right: <span class="hljs-number"><span class="hljs-number">12</span></span>
})
.cornerWhiteBg()

} }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

3,item点击的时候,动态更改checked属性

 List({ space: 8 }) {
LazyForEach(this.ds, (it: FlashNewsModelWithTitle) => {
ListItemGroup({ header: this.ItemHeader(it.title), space: 8 }) {
LazyForEach(this.dsInners.get(it.title), (it: FlashNewsModel) => {
ListItem() {
ItemFlashNews({ m: it }).onClick(() => {
// 动态更新 checked属性的值
it.checked = !it.checked
})
}
}, (it: FlashNewsModel) => it.id.toString())
}
}, (it: FlashNewsModelWithTitle) => it.title.toString())
}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

回到顶部