HarmonyOS 鸿蒙分组列表的高效懒加载实现
HarmonyOS 鸿蒙分组列表的高效懒加载实现
<markdown _ngcontent-brp-c237="" class="markdownPreContainer">
双重嵌套列表,两个列表都实现懒加载效果
效果图如下:
实现的主逻辑如下:
- 日期header使用一个DataSource
- 使用一个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 联系官网客服。
可以呀,选中跟平常的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>