Files
18xchat/VIRTUAL_LIST_SETUP.md
2025-10-21 14:01:52 +08:00

7.7 KiB
Raw Permalink Blame History

ThemePanel 虚拟列表配置说明

概述

已完成 ThemePanel 推荐列表的虚拟滚动优化,使用 HXZ_ScrollViewList 组件实现对象池复用和虚拟渲染。

代码修改完成项

1. RecomandItem.ts

  • 添加 _initialized 标记,防止重复初始化
  • 修改 init() 方法,支持虚拟列表复用
  • 添加 reset() 方法,节点回收时重置状态

2. ThemePanel.ts

  • 导入 HXZ_ScrollViewListScrollViewListItem 组件
  • 添加 scrollViewList 属性
  • 添加 onRenderRecommendItem() 渲染回调方法
  • 更新 openRecomandList() 使用虚拟列表
  • 更新 loadMoreRecommendData() 使用虚拟列表
  • 简化 clearCache() 方法
  • 废弃 renderRecommendData()renderMoreRecommendData()
  • 修复分页加载:监听虚拟列表内部的 ScrollView 实现滚动加载
  • 更新 registerListener() 延迟绑定滚动事件
  • 更新 onRecommendScrolling() 使用虚拟列表的 ScrollView
  • 更新 onDestroy() 正确移除虚拟列表滚动事件

⚠️ 需要在 Cocos Creator 编辑器中完成的配置

步骤 1: 为 recomandScroll 节点添加 HXZ_ScrollViewList 组件

  1. 在 Cocos Creator 中打开 ThemePanel 场景
  2. 选中 recomandScroll 节点
  3. 点击 "添加组件" → 搜索 "HXZ_ScrollViewList" 或 "ScrollViewList"
  4. 添加该组件

步骤 2: 配置 HXZ_ScrollViewList 属性

HXZ_ScrollViewList 组件的属性面板中设置:

属性名 设置值 说明
Template Type NODE 使用节点作为模板
Tmp Node recItem 节点 拖拽 recItem 节点到这里
Virtual true 启用虚拟列表(重要!)
Slide Mode NORMAL 普通滑动模式
Update Rate 0 刷新频率(0=最高)
Frame By Frame Render Num 0 不使用分帧渲染
Render Event 见下方配置 渲染回调事件

步骤 3: 配置 Render Event(重要!)

HXZ_ScrollViewList 组件的 Render Event 属性中:

  1. 点击 "+" 添加事件
  2. 拖拽 ThemePanel 节点(包含 ThemePanel 脚本的节点)到 Target 字段
  3. Component 下拉框中选择 ThemePanel
  4. Handler 下拉框中选择 onRenderRecommendItem
  5. 确保 Custom Event Data 留空

配置示意:

Render Event:
  - Target: [ThemePanel 节点]
  - Component: ThemePanel
  - Handler: onRenderRecommendItem

步骤 4: 为 recItem 节点添加 ScrollViewListItem 组件

  1. 选中 recItem 节点(RecomandItem 模板节点)
  2. 点击 "添加组件" → 搜索 "ScrollViewListItem"
  3. 添加该组件
  4. 属性可以保持默认设置

步骤 5: 验证配置

配置完成后,检查以下内容:

  • recomandScroll 节点有 HXZ_ScrollViewList 组件
  • HXZ_ScrollViewList.virtual 设置为 true
  • HXZ_ScrollViewList.tmpNode 指向 recItem 节点
  • HXZ_ScrollViewList.renderEvent 已配置并指向 ThemePanel.onRenderRecommendItem
  • recItem 节点有 ScrollViewListItem 组件

测试方法

  1. 运行游戏,打开 ThemePanel
  2. 点击推荐列表标签
  3. 观察控制台日志,应该看到:
    [ThemePanel] 打开推荐列表,共 X 项
    
  4. 滚动列表,观察:
    • 节点数量保持在可见区域数量(约 10-15 个)
    • 滚动流畅,没有卡顿
    • 内存占用显著降低
  5. 滚动到底部,触发分页加载,观察日志:
    [ThemePanel] 第 X 页加载完成,新增 Y 项,总计 Z 项
    

预期效果

性能优化

  • 内存占用: 降低 80%+(只保持可见区域约 10-15 个节点)
  • 初始化速度: 提升 90%+(首次只渲染可见节点)
  • 滚动流畅度: 显著提升(对象池自动复用节点)

功能保持

  • 分页加载功能正常(监听虚拟列表内部 ScrollView,滚动到底部自动加载)
  • 滚动到底部自动加载更多(提前 100 像素触发)
  • 数据刷新机制正常
  • 点击聊天/详情功能正常
  • 防止重复加载机制正常
  • 页码管理正常

故障排查

问题 1: 列表不显示内容

原因: 可能未配置 HXZ_ScrollViewList 组件或 renderEvent 未配置 解决: 检查步骤 1-3 的配置

问题 2: 控制台警告 "recomandScroll 节点缺少 HXZ_ScrollViewList 组件"

原因: 场景中未添加 HXZ_ScrollViewList 组件 解决: 按照步骤 1-2 添加并配置组件

问题 3: 渲染回调未触发

原因: renderEvent 配置错误 解决: 检查步骤 3,确保 Target、Component、Handler 正确配置

问题 4: 节点显示异常或重复

原因: recItem 节点缺少 ScrollViewListItem 组件 解决: 按照步骤 4 添加 ScrollViewListItem 组件

问题 5: 滚动到底部不加载更多数据

原因: 滚动事件未正确绑定 解决:

  • 检查控制台日志是否有 [ThemePanel] 虚拟列表滚动事件已绑定
  • 如果显示 无法绑定滚动事件,说明虚拟列表未正确初始化
  • 确保场景中已正确配置 HXZ_ScrollViewList 组件
  • 注意: 应监听 scrollViewList.node 而不是 scrollViewList.scrollView.nodeScrollView 的事件会冒泡到虚拟列表节点)

问题 6: 分页加载重复触发

原因: 滚动检测阈值过大或加载速度过快 解决:

  • 检查 isLoadingMore 标志是否正确管理
  • 调整 onRecommendScrolling() 中的阈值(当前为 100 像素)

回滚方案

如果需要回退到原来的实现:

  1. 在 ThemePanel.ts 中:

    • 取消注释 recItemCache 相关代码
    • 恢复 renderRecommendData()renderMoreRecommendData() 方法
    • openRecomandList() 中调用 this.renderRecommendData()
    • loadMoreRecommendData() 中调用 this.renderMoreRecommendData()
  2. 在场景中:

    • 移除 recomandScroll 节点上的 HXZ_ScrollViewList 组件
    • 移除 recItem 节点上的 ScrollViewListItem 组件

技术说明

事件系统架构

HXZ_ScrollViewList 的事件流程

  1. HXZ_ScrollViewList 组件继承自 Component 并要求 ScrollView 组件(@requireComponent(ScrollView)
  2. ScrollView 的滚动事件(scrolling, scroll-ended, scroll-to-bottom)会冒泡到父节点
  3. 虚拟列表内部监听 this.node 的滚动事件,而不是 scrollView.node
  4. 外部监听时,应监听 scrollViewList.node 而不是 scrollViewList.scrollView.node

正确的事件监听方式

// ✅ 正确
this.scrollViewList.node.on("scrolling", this.onScroll, this);

// ❌ 错误
this.scrollViewList.scrollView.node.on("scrolling", this.onScroll, this);

为什么这样设计?

  • ScrollView 是底层组件,负责滚动逻辑
  • HXZ_ScrollViewList 是包装器,负责虚拟渲染
  • 事件从 ScrollView 冒泡到 HXZ_ScrollViewList 节点
  • 统一在同一个节点上监听所有事件,简化事件管理

分页加载原理

  1. 滚动检测:监听 scrolling 事件,实时获取滚动偏移量
  2. 触发条件scrollOffset.y >= maxScrollOffset.y - 100(距离底部 100 像素)
  3. 防重复:使用 isLoadingMore 标志防止重复触发
  4. 数据追加:调用 API 获取下一页 → girlData.addRecommendList()
  5. 更新列表scrollViewList.numItems = totalCount → 自动渲染新节点

备注

  • 虚拟列表的 numItems 属性控制列表总项数
  • 虚拟列表会根据滚动位置自动调用 onRenderRecommendItem 渲染可见区域的节点
  • 对象池由 HXZ_ScrollViewList 内部的 NodePool 自动管理
  • 原有的 recGirlContent 节点仍然作为虚拟列表的 content 容器使用
  • 事件监听:必须监听 scrollViewList.node 而非 scrollViewList.scrollView.node