【好用的虚拟列表】已完结,大家快来围观

直接体验

话不多说,直接上链接在线体验

买家评价

随便说说

本组件,专为在游戏展示大量数据列表的场景而设计。它在保证流畅渲染的同时,通过动态节点管理和复用技术避免带来的性能开销。相较于原生ScrollView,它大幅提升滚动性能和内存利用率,显著降低开发成本。

效果展示

具体包含哪些功能,请看下面的GIF

主要功能点

  • 使用简单:使用简洁,注释清晰

  • 多种布局:垂直、水平、网格、多模板布局

  • 自适应刷新频率: 减少运算,提高性能
    8.jpg

  • 自定义缓存区大小: 提前加载,避免卡顿
    9.jpg

  • 自适应性能参数:性能参数,自适应计算

  • 自定义模板:注册不同模板类型

  • 支持嵌套: 通过触摸事件复制传递,保证在内部滚动列表的触摸事件,可以传递到外部虚拟列表。

  • 分帧加载:通过分帧加载技术,避免一次性加载大量数据导致的性能问题,确保界面流畅。

  • 节点池管理:使用节点池管理机制,复用节点,减少频繁创建和销毁节点带来的性能开销。

  • 防抖动处理:在滚动事件中加入防抖动处理,避免频繁触发更新操作,提高性能。

  • 动态修改Item数据并更新:支持动态修改列表项的数据,并实时更新显示内容。

  • 动态修改Item尺寸:支持动态修改列表项的尺寸,并自动调整布局。

  • 高度复用:通过节点池和分帧加载机制,实现节点的高度复用,减少内存占用。

  • 低Drawcall:优化渲染流程,减少Drawcall次数,提高渲染性能。

使用教程

  1. 初始化虚拟列表

  2. 数据驱动刷新列表

  3. 触发Item回调

常用接口

  • ReloadData:重载数据,刷新列表
/**
  * 重新加载数据源,根据数据长度初始化各项尺寸
  * @param dataSource 数据源数组,每项需包含type属性指定模板类型
  * @param customSize 可选的自定义尺寸数组,长度应与dataSource相同
public ReloadData(dataSource: any[], customSize: number[] = []): void;
  • InsertItemAt:指定位置插入Item
/**
  * 在指定位置插入项目
  * @param index 插入位置索引
  * @param data 要插入的数据
  * @param animate 是否使用动画效果
  */
public InsertItemAt(index: number, data: any, animate: boolean = false): void
  • RemoveItemAt:指定位置删除Item
/**
  * 移除指定位置的项目
  * @param index 要移除的项目索引
  * @param animate 是否使用动画效果
  */
public RemoveItemAt(index: number, animate: boolean = false): void;
  • RegisterTemplate: 注册Item模板
/**
  * 注册模板类型
  * @param type 模板类型标识符
  * @param nodeOrGetter 模板节点或获取节点的函数
  * @param isDefault 是否设为默认模板
  */
public RegisterTemplate(type: string | number, nodeOrGetter: Node | (() => Node), isDefault: boolean = false): void;
  • ScrollToIndex:滚动到指定索引项,使该项出现在屏幕正中央
/**
  * 滚动到指定单元格,使该单元格所在行(或单个项)居中显示
  * @param index 目标单元格索引
  * @param duration 滚动动画时长(秒)
  * @param callback 滚动完成回调
  */
public ScrollToIndex(index: number, duration: number = 0.3, callback?: () => void);
  • UpdateItemSize:更新指定索引项的尺寸
/** 
  * 更新指定单元格的尺寸(动态修改后重排) 
  * 暂不支持网格布局
  */
public UpdateItemSize(index: number, newSize: number);
  • UpdateItemAt:更新指定索引项的数据
/** 
  * 更新指定单元格(若可见则调用更新回调)
  */
public UpdateItemAt(index: number, data: ItemTemplateData);
  • Refresh:刷新列表数据或尺寸变化后调用
/** 
  * 刷新列表(数据或尺寸变化后调用) 
  */
public Refresh();

技术交流

Cocos 官方推荐文章
技术分享 - 性能优化
技术分享 - 嵌套支持

版本记录(持续更新中)

1.8.0(2025年6月21日)

  • 增加加载完成回调onLoadFinished
  • 优化UpdateItemAt,方便更新数据

1.7.0(2025年6月17日)

  • 支持虚拟列表嵌套使用,内部触摸事件传递
  • 支持自定义尺寸布局,提前传入尺寸加载
  • 新增性能监控功能,掉帧自适应调节刷新率

1.6.0(2025年5月28日)

  • 支持paddingTop、paddingBottom、paddingLeft、paddingRight属性设置
  • 新增动画队列,防止快速插入和删除Item显示异常
  • 代码优化调整

1.5.0(2025年5月22日)

  • 网格布局支持动态插入
  • 网格布局支持动态删除
  • 动态插入和删除支持动画参数
  • 新增Clear接口

1.4.0(2025年5月12日)

  • 支持多模板虚拟列表
  • 支持列表动态插入
  • 支持列表动态删除
  • 修复销毁虚拟列表报错问题

1.3.0(2025年4月30日)

  • 修复快速滚动出现的闪屏问题
  • 修复滚动底部异常问题
  • 调整性能参数,快速滚动时提高帧率
  • 优化分帧加载策略,只在必要时启动

1.2.0(2025年4月18日)

  • 新增预加载缓冲区设定
  • 自适应刷新频率提高性能
  • 优化Demo代码
  • 换肤提高品质

1.1.0(2025年3月12日)

  • 支持网格布局
  • 组件选项优化处理

1.0.0(2025年3月6日)

  • 初始版本发布
  • 实现基本的虚拟列表功能
  • 支持动态修改Item数据和尺寸
  • 新增分帧加载功能
  • 优化节点池管理机制
  • 增加防抖动处理

商城链接

感兴趣的小伙伴可以了解下

5赞

你一共发了9个帖子,全是这个虚拟列表 :rofl:

2赞

真的很不错,更新也很勤,好用

1赞

楼主其他虚拟列表的贴子已全部删除,仅保留这一个。
感谢大家的监督
也感谢楼主的持续输出,希望后面可以分享更多技术干货。
对于虚拟列表这个话题,也可以继续分享,但应避免重复,可以从不同的案例、不同的层次、不同的角度进行。

再次感谢!

哈哈哈哈哈哈哈哈 还得是你

虽然没有证据,但是怀疑3楼大概是帖主被禁言后的小号 :sweat_smile:

1赞

我看你也有一个虚拟滚动+分层渲染 ,但没怎么宣传呢。 也建议大佬多多分享。

想太多了 我自己买的东西说两句都不行了吗,人家也确实在经常更新 111

嗯嗯。退一步海阔天空,毕竟大家都是发着光的人。

  1. 鼓励活跃的分享者
  2. 也会惩罚高频的重复内容
  3. 允许同一个方向不同的产品出现
  4. 鼓励良性竞争,靠产品质量和内容说话

额,平时比较忙,而且论坛也有很多很好用的免费虚拟列表,没必要一定要买我的。话说官方真不打算提供一个简易版的虚拟列表吗?感觉需求确实很大啊,特别是2D开发

1赞

感谢大家支持,最近更新了一下,大家有建议可以提哈

用起来很丝滑,更新频率很高,赞:+1:

1赞

用起来很丝滑,尤其是大量的图片从服务端加载的时候,加载起来很流畅。

1赞

好用的东西,应该更多人知道,组件会主句更新,会越来越完善。

PS: 现有的用户已经有200+,目前价格99,享受终身免费更新,后续会逐步恢复原价,早买早享受,直通车

点进去体验版,看到一个问题,显示区域不包含第三项的时候,我删除了第三项,为什么列表的显示内容刷新了?理论上不应该刷新。

然后滚动到第二十个的逻辑也不对,第20个只显示了一半,要完整显示。

然后你网络水平跳转和竖直跳转的位置不一样。竖直的显示在第一行,水平的显示在中间。

其他的还没认真体验,看过去还是有待优化:joy:

我昨天也测出了一个bug 先点击删除第三个后再点击更新第80个 这个时候会更新80、81两个

支持下拉加载吗?

  1. 不包含第三个时候,删除第三个,后面的item需要往上移动呀,比如聊天系统,难道撤回一条消息,其他的不往上顶嘛?

  2. 删除了几个Item,idx = 20的item已经不是第20个呀,看图你是删除了3个Item

  3. 这一点没居中确实有点问题,需要优化下。

感谢大佬的反馈 :grinning:

已经修复啦,感谢大佬反馈

这不得每条评论底下都发一遍 :smiley: