这是一个基于Cocos Creator写的虚拟列表组件。本组件是配合 Cocos Creator 本身的滚动窗结构去写的,所以在编辑器中操作会很方便,所见即所得。
在线 DEMO(请科学上网):
Cocos 论坛帖子链接:
- 所有类型布局。(单列、单行、网格,甚至各种花式 RIGHT_TO_LEFT、BOTTOM_TO_TOP)
- 分帧渲染。
- 循环列表。
- 选择模式。(单选、多选)
- 滑动模式。(普通、粘附、分页)
- 动态 Item 宽/高。(用来做聊天列表再适合不过)
- 动态删除 Item 项。
- ...
Last test by ccc_v2.4.6 and ccc_v3.2.1
我的邮箱:[email protected]
- 主要依赖于
List
和ListItem
这两个脚本,先将这两个脚本放置到你的项目中。 - 在编辑器中,创建一个ScrollView(也就是ScrollView->Mask->Content这样层级结构的节点!)。
- 将
List
组件挂载到ScrollView节点上。 - 设置模板 Item,选择
TemplateType
,可切换模板类型,请按需选择。 - 设置滑动模式(
SlideMode
),NORMAL=通常
,ADHERING=粘附
,PAGE=分页
,三选一。 - 设置是否为虚拟列表(
Virtual
),默认为true
,意思是仅在可视范围内渲染Item
。反之,如果为false
,则会渲染所有数量的 Item,一般不推荐这么做,但凡事总有个万一,所以预留了。 - (可选)设置逐帧渲染(
FrameByFrameRenderNum
),该数量为每帧渲染的数量。 - 设置渲染器(
RenderEvent
),在View中写一个函数,将该函数指向RenderEvent,运行时,设置 List 数量,Item 将会通过该函数进行回调,开发者在该函数中实现Item 的刷新。 - (可选)设置选择模式(
SelectedMode
),选择模式有SINGLE(单选)
、MULT(多选)
两种,须将cc.Button
和ListItem
挂载到模板 Item上。在View中写一个函数,将该函数指向SelectedEvent
,运行时,当选择变更,将会通过该函数回调。
在View中,若是单选模式,用
list.selectedId=Number
来改变当前选择。若是多选模式,则调用list.setMultSelected(args, boolean)
接口来设置多选数据。
- 完成以上设置后,在View中调用
list.numItems=Number
设置列表数量,本组件就会通过渲染器(即RenderEvent
)进行回调了!
- 每一个
Item-Node
都会被赋值一个_listId
,即该Item
在List
中的下标
。假如你的Item
是个按钮
,在该按钮
的回调事件
中,通过event.currentTarget._listId
就能取得该Item的下标
了,这非常方便。(TS版
比较特殊, 通过event.currentTarget['_listId']
来获得。) - 如果是虚拟列表(即
virtual
属性为true
),勾选ListItem
的adaptiveSize
属性,能实现动态Item宽/高
。
- 本组件所依赖的ScrollView 节点、Mask 节点以及Content 节点,这三个节点的锚点需要按方向去设置。比如从顶到底单列排列,就需要设置锚点为(0.5, 1)。如果是从左到右网格排列,就需要设置锚点为(0, 1)。始终将锚点设置到首个 Item那一边。
- 理论上设为虚拟列表后不可再设回普通列表(即
virtual
属性)。 - SlideMode 设为
ADHERING(粘附)
或PAGE(页面)
后,组件将强行屏蔽惯性滚动。 - 设为
循环列表
时,Content
的cc.Layout
的边缘距离(top/bottom/left/right)
要设置成与spacingX/Y(间距)
一样。(因为在循环列表中,边距=间距)
。
- 下拉刷新。
- 循环列表
PAGE
版。
PAGE
模式下,目前是靠pageDistance
变量来控制翻页响应距离
,如果滚动窗口很小,玩家拖动时一次性能拖(翻)1 页以上,那就会存在问题。
模板 Item 类型,分别有 Node 和 Prefab 两种类型可选。
meta | description |
---|---|
类型 | List.TemplateType |
模板 Item 节点。
meta | description |
---|---|
类型 | Node |
模板 Item 预制体。
meta | description |
---|---|
类型 | Prefab |
滑动模式。分别有 3 种滑动模式:普通、粘附、页面。
meta | description |
---|---|
类型 | List.SlideType |
翻页作用距离。(仅滑动模式为页面
时有效)
meta | description |
---|---|
类型 | Number |
翻页响应事件。
meta | description |
---|---|
类型 | Component.EventHandler |
是否为虚拟列表。
meta | description |
---|---|
类型 | Boolean |
是否为循环列表。
meta | description |
---|---|
类型 | Boolean |
是否在 Item 数量不足以填满 Content 时,居中显示 Item(不支持 Grid 布局)。
meta | description |
---|---|
类型 | Boolean |
是否在 Item 数量不足以填满 Content 时,可滑动列表。
meta | description |
---|---|
类型 | Boolean |
刷新频率(值越大刷新频率越低、性能越高)。
meta | description |
---|---|
类型 | Number |
分帧渲染时,每帧渲染的 Item 数量(<=0 时则关闭分帧渲染)。
meta | description |
---|---|
类型 | Number |
渲染事件。
meta | description |
---|---|
类型 | Component.EventHandler |
选择模式。分别有 2 种选择模式:单选、多选。
meta | description |
---|---|
类型 | List.SelectedType |
选择响应事件。
meta | description |
---|---|
类型 | Component.EventHandler |
当前选择索引,可通过设置此属性变更选择。
meta | description |
---|---|
类型 | Number |
Item 总数,设置此属性后,List 会调用 renderEvent 以渲染 Item。
meta | description |
---|---|
类型 | Number |
可供开发者调用的方法都在下面,具体参数就不写了,去看源码吧 ( ̄ ▽  ̄)"。
设置模板 Item。
检查是否已初始化。
粘附到最近的一个 Item。
设置多选数据。
更新单个 Item。
更新全部 Item。
根据索引获取 Item。(虚拟列表有可能无法获取到 Item,因为 Item 可能并未出现在视口内)
动销删除单个 Item。(使用方法可参考示例项目)
滚动到指定索引 Item 处。
上一页。(仅滑动模式为 PAGE
时可用)
下一页。(仅滑动模式为 PAGE
时可用)
跳转至指定页。(仅滑动模式为 PAGE
时可用)
又是时隔大半年的更新,就...适配新版本。
示例项目升级至 ccc_v2.4.6。 示例项目升级至 ccc_v3.2.1。
时隔大半年的更新,主要还是填一些坑。 看到3.0预览版出来了,有点感慨,总之,希望ccc越来越好吧。 仓库里也新增了3.0版本的List,估计坑很多,期望值别太高。
示例项目升级至 ccc_v2.4.3。
- 感谢
妖怪香蕉
帮我修复了分帧渲染
可能会重复渲染多次的问题。 - 修复边距(Padding)较大时,
Item
回收判定错误的 BUG。(感谢 Cocos 论坛用户@290027085
) - 修复
PAGE
模式下,手动滑动到最后一页,再往后拖一下,使范围外的Item
都被回收,然后再scrollTo
到中间的页,会自动多跳一页的 BUG。(感谢 GitHub 用户shangdibaozi
) - 新增多选数据接口
getMultSelected
、hasMultSelected
。(感谢 GitHub用户@ckcfcc
提出建议)
- 修复 TS 版
单选/多选
时,缺少参数的 BUG。(感谢 Cocos 论坛用户@455073646
)
示例项目升级至 ccc_v2.3.2。(CocosDashboard 真香)
- 修复
自适应宽/高(AdaptiveSize)
时,调用List.scrollTo(...)
可能会乱跳的 BUG。(感谢幻 <*****[email protected]>
)
示例项目升级至 ccc_v2.3.1。
- 修改了
模板Item
的销毁机制,现在支持同一个View
下,多个List
的模板Item
引用同一个Node
。 - 修复使用
自适应宽/高(AdaptiveSize)
时,可能显示不完全的 Bug。(感谢 Cocos 论坛用户@icicic
) - 优化
分帧加载(FrameByFrameRenderNum)
时,滚动时刷新频率过高的问题。(感谢 Cocos 论坛用户@lifeiying
) - 优化
选择模式(SelectedMode)
的使用习惯。现在允许将按钮组件
挂载到模板Item
下的子节点上,当然,这样用的话,需要自行添加模板Item的ListItem的onClickThis
到该按钮组件的Click Events
上。
示例项目升级至 ccc_v2.2.2。
- 修复连续调用两次
scrollTo
可能会卡住的 BUG。 - 修复
Selected Event
报错。
- 以后都不推荐在外部计算
customSize
或是手动调用calcCustomSize
函数。 现在要实现动态宽/高
,请给模板Item
挂载ListItem组件
,并勾选adaptiveSize
属性即可,惊不惊喜,意不意外?使用方法请看示例项目
中的TestAdaptive
场景。(感谢 Cocos 论坛用户@bluesn
给出的建议)另外,
List.customSize
变量已更名为_customSize
。calcCustomSize
函数将会持续保留,某些特殊场景还是用得到的。 - 解决
List
销毁时,有可能存在内存泄漏的 BUG。 - List 初始化时会实例化一个
模板Item
缓存起来,并将原有引用的模板Item
销毁。所以以后不支持两个List
的模板Item
引用同一个Node
。(Prefab
则没有这个限制);
- 修复使用
循环列表+单/多选模式
时,选择回调事件
的参数可能会超过numItems(或数据数组长度)
的 BUG。 - 修复示例项目
Main.scene
的报错。
示例项目升级至 ccc_v2.2.1。
- 适配
cc.Widget
。(感谢 Cocos 论坛用户@ckcfcc
) - 新增
TestWidget.scene
示例场景。 - 新增
循环列表
功能,即cyclic
属性。(目前仅支持单行/单列)设为循环列表时,Content 的 cc.Layout 边缘距离(top/bottom/left/right)要设置成与 spacingX/Y(间距)一样。(因为在循环列表中,边距=间距)。
- 新增
TestCyclic.scene
示例场景。
- 新增
LakeSlide
属性。当该属性为true
,Item 数量不足以填满Content
时,也可以滑动。(默认为false
,与LakeCenter
属性相斥)
- 修复
ListItem
可能会丢失事件的 BUG。
示例项目升级至 ccc_v2.2.0。
- 修复
List
销毁时,对象池中的Item
未执行销毁的 BUG。 - 修复
PAGE
模式下,滑动翻页可能会跳页异常的 BUG。 - 修复
模板Item
可能被误销毁的 BUG。 - 修复当
List
节点的Size
改变时,List
未刷新的 BUG。
- ccc_v2.2.0 的 cc.ScrollView 有个 BUG,就是滑动时,惯性滚动到边缘没有回弹效果,这不是本组件的问题,等待官方更新修复。
- 这个组件我也是佛系更新,只要官方的新版本不魔改,一般来说都是向上兼容的。
- 新增
背包
示例场景(TestBag.scene
)。
- TS 版,
模板Item
取消强制挂载ListItem
,现可通过item['_listId']
来获取Item下标
。 - 新增
单选模式
下repeatEventSingle
属性,为true
时,可重复触发相同的单选事件。 - 修复滑动
ScollView
时,鼠标拖到ScollView
之外,会中止滚动的 BUG。 - 修复
SlideMode
为PAGE
或ADHERING
时,滚动ScollView
容易卡住的 BUG。
- 新增
TestCustomSize
场景例子,着重演示如何用本组件实现聊天列表
。 - 优化局部代码,提升一丁点效率。
- 将
updateAppointed
接口更名为updateItem
。 - 新增
updateAll()
接口。
- 新增
LakeCenter
属性。当该属性为true
,Item 数量不足以填满Content
时,会居中显示所有 Item。(不支持GRID
布局) - 新增
calcCustomSize
接口,方便开发者计算CustomSize
。(如果模板 Item 的结构较复杂,建议还是在外部自行计算) - 修复反方向布局,Item 数量过少时,会向正方向对齐的 BUG。
- 滑动模式新增
PAGE
模式,用来做分页效果,可自定义翻页滑动响应距离(pageDistance
)。建议不要再用ADHERING
模式去实现分页效果。关于PAGE
模式下的接口:list.prePage(timeInSecond)
、list.nextPage(timeInSecond)
、list.skipPage(pageNum, timeInSecond)
,分别是上一页、下一页、跳转到指定页数。 - 优化效率。
- 新增 TS 版本。
- 优化效率。
- 修复滑动模式为吸附(ADHERING)时,还未吸附到目标点时,点击滚动窗,再松开,会吸附失败的 BUG。
- 独立吸附接口
list.adhere()
,可外部调用,不限滑动模式。
- 支持
BOTTOM_TO_TOP
,RIGHT_TO_LEFT
布局。需要注意:各种反方向排列的布局(BOTTOM_TO_TOP
、RIGHT_TO_LEFT
)都会有问题(item 数量过少,就会导致 Content 错位),这个是官方问题。而本组件是配合cc.ScrollView
去写的,所以也不支持,待官方后续优化(Last test by Creator_v2.1.1)。如果 Item 数量很多,那么可以使用。
- 单列布局时支持自定义指定 Item 的 height。单行布局时支持自定义指定 Item 的 width。通过
list.customSize = {0:100, 1:130, 5:120, ...}
来设置,其中 key 为 Item 的 ID,value 为 height/width,没有找到该 Item 的 customSize 将会与模板 ItemSize 一致。
- 新增 List 的配套组件----
ListItem
。 - 新增选择模式。
- 新增带动画删除 Item 接口
list.aniDelItem(id, callFunc, aniType)
,因本组件毕竟还是数据驱动,所以请务必在 callFunc 中删除数据数组中相应下标的数据,然后手动更新该 list(即list.numItems=Number
)。