鸿蒙在处理长列表和嵌套滑动处理,相比于安卓和ios 就简单许多了,通过 LazyForEach 和 List 上面的
php
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
就可以实现了

scss
// BasicDataSource实现了IDataSource接口,用于管理listener监听,以及通知LazyForEach数据更新
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: string[] = [];
public totalCount(): number {
return this.originDataArray.length;
}
public getData(index: number): string {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为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);
// 写法2:listener.onDatasetChange([{type: DataOperationType.ADD, index: index}]);
});
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.CHANGE, index: index}]);
});
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
// 写法2:listener.onDatasetChange([{type: DataOperationType.DELETE, index: index}]);
});
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
// 写法2:listener.onDatasetChange(
// [{type: DataOperationType.EXCHANGE, index: {start: from, end: to}}]);
});
}
notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
});
}
}
class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
@Entry
@Component
struct Index {
private data: MyDataSource = new MyDataSource();
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(`Hello ${i}`);
}
}
@Styles
listCard() {
.backgroundColor(Color.White)
.height(72)
.width("100%")
.borderRadius(12)
}
build() {
Scroll() {
Column() {
Text("顶部区域")
.width("100%")
.height("20%")
.backgroundColor('#0080DC')
.textAlign(TextAlign.Center)
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
List({ space: 10 }) {
LazyForEach(this.data, (item: number) => {
ListItem() {
Text("item" + item)
.fontSize(16)
.height(50)
}.listCard()
}, (item: string) => item)
}.width("100%")
.edgeEffect(EdgeEffect.Spring)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
}.tabBar("我的")
TabContent() {
List({ space: 10 }) {
LazyForEach(this.data, (item: number) => {
ListItem() {
Text("item" + item)
.fontSize(16)
.height(50)
}.listCard()
}, (item: string) => item)
}.width("100%")
.edgeEffect(EdgeEffect.Spring)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
}.tabBar("设置")
}
.vertical(false)
.height("100%")
}.width("100%")
}
.edgeEffect(EdgeEffect.Spring)
.friction(0.6)
.backgroundColor('#DCDCDC')
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
}
}