HarmonyOS鸿蒙Next中List包裹Repeat开启虚拟滚动数据量大的时候调用scrollTo回到顶部会卡顿
HarmonyOS鸿蒙Next中List包裹Repeat开启虚拟滚动数据量大的时候调用scrollTo回到顶部会卡顿
scrollTo({
xOffset: 0, yOffset: 0
})
List 包裹Repeat 开启虚拟滚动
数据有八百多条 手动滑倒最底部
这个时候调用scrollTo 回到顶部会卡顿2 秒钟 才会回到顶部
开发者你好,可以参考以下方案优化性能:
【解决方案】 可以采用先调用scrollToIndex关闭动画跳转到目标附近位置,再调用scrollToIndex开启动画滚动到目标位置的间接跳转的方式,优化性能。 以纵向滚动的5000个元素的长列表,调用scroller反复滚动到列表顶部和底部为例,示例代码如下:
@Entry
@ComponentV2
export struct virtrulScroll {
private itemHeight: number = 50;
private readonly list: string[] = Array
.from({ length: 5000 }, (_: number, i: number) => i + 1)
.map((i: number) => `index: ${i}`);
private readonly scroller: Scroller = new Scroller();
build() {
Column() {
Row({ space: 10 }) {
Button('scroll to top')
.fontSize(13)
.onClick(() => {
// 用currentOffset().yOffset获取当前滑动偏移量除以单项高度获得index做判断,离目标位置超过200项则以关闭动效先滚动到目标位置附近
if (this.scroller.currentOffset().yOffset / this.itemHeight >= 200) {
this.scroller.scrollToIndex(200, false);
}
this.scroller.scrollToIndex(0, true);
});
Button('scroll to bottom')
.fontSize(13)
.onClick(() => {
if (this.scroller.currentOffset().yOffset / this.itemHeight <= this.list.length - 200) {
this.scroller.scrollToIndex(this.list.length - 200, false);
}
this.scroller.scrollToIndex(this.list.length - 1, true);
});
Button('jump 1000')
.fontSize(13)
.onClick(() => {
console.info('currentoffset: ', this.scroller.currentOffset().yOffset);
this.scroller.scrollToIndex(1000, false);
});
};
List({
scroller: this.scroller,
}) {
Repeat(this.list)
.key((item: string) => item)
.virtualScroll({ totalCount: this.list.length })
.templateId(() => '1')
.template('1', (repeatItem: RepeatItem<string>) => {
ListItem() {
Text(repeatItem.item)
.width('100%')
.height(this.itemHeight)
.padding(5)
.textAlign(TextAlign.Center);
};
})
.each((repeatItem: RepeatItem<string>) => {
ListItem() {
Text(repeatItem.item)
.width('100%')
.height(this.itemHeight)
.padding(5);
};
});
}
.width('100%')
.height(200)
.layoutWeight(1);
}.backgroundColor(Color.White);
}
}
或者可以考虑使用Repeat的virtualScroll模式。Repeat根据容器组件的有效加载范围(可视区域+预加载区域)加载子组件。当容器滑动/数组改变时,Repeat会根据父容器组件传递的参数重新计算有效加载范围,实时管理列表节点的创建与销毁。该模式适合需要懒加载的长数据列表/通过组件复用优化性能表现的场景。
更多关于HarmonyOS鸿蒙Next中List包裹Repeat开启虚拟滚动数据量大的时候调用scrollTo回到顶部会卡顿的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
**问题描述:**在list中使用scrollTo方法会卡两秒
详细分析:
scrollTo({yOffset:0,xOffset:0})
根据api分析,滚动时需要计算x和y的偏移量,有一个计算的过程,如果数据量过大,就会导致计算时间的增加,这是他卡顿的原因
**解决方案:**如果你是为了实现回到顶部的功能,可以通过一下两个api实现:
方法一:
this.scroller.scrollToIndex(0)
方法二:
this.scroller.scrollEdge(Edge.Top)
因为这两个api不涉及计算,所以速度很快,经过验证,没有任何卡顿
如果对你有帮助,望采纳!
在HarmonyOS Next中,List组件包裹Repeat组件并开启虚拟化后,数据量过大时scrollTo操作卡顿是由于虚拟滚动机制下渲染节点回收与复用导致。当执行快速定位时,系统需重新计算布局并渲染可视区域外内容,引发性能瓶颈。可通过以下方案优化:1. 使用LazyForEach替代Repeat实现动态加载;2. 设置cachedCount属性预缓存可视区外节点;3. 分批加载数据避免单次渲染过量条目。需确保scrollTo调用时机在列表渲染稳定后。


