import { _decorator, Component, Node, instantiate, tween, Vec3, Label, } from "cc"; import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView"; import Utils from "db://assets/Scripts/Main/Common/Utils"; import { GButton } from "db://assets/Scripts/Main/Common/GButton"; import { GirlListItem } from "../../uiitems/GirlListItem"; import { GirlService } from "db://assets/Scripts/chat18x/network/services/GirlService"; import { DataManager, DataId } from "../../data/DataManager"; import { GirlData } from "../../data/GirlData"; import proto from "db://assets/Scripts/proto/proto.pb.js"; import { NavigationManager, PanelType } from "../../manager/NavigationManager"; import { ThemeData } from "../../data/ThemeData"; import LanguageUtils from "../../../Main/Common/LanguageUtils"; import HXZ_ScrollViewList from "db://assets/Scripts/Main/Common/ScrollViewList"; import { logger } from "db://assets/Scripts/Main/Common/Logger"; const { ccclass, property } = _decorator; @ccclass("GirlCollectionPanel") export class GirlCollectionPanel extends li_BaseView { private _nodeTab: any = {}; itemInst: GirlListItem; scrollView: Node; // 虚拟列表组件 private scrollViewList: HXZ_ScrollViewList = null; // 收藏ID缓存(按收藏时间排序) private cachedBookmarkIds: number[] = []; private title1: Label; private title2: Label; onLoadCT() { this.node.active = false; this.scheduleOnce(() => { this.node.active = true; }, 0.1); Utils.parseNode(this.node, this._nodeTab); this.registerListener(); this.itemInst = this._nodeTab.BubbleItem.getComponent(GirlListItem); this.itemInst.node.active = false; this.scrollView = this._nodeTab.ScrollView; this.title1 = this._nodeTab.title1.getComponent(Label); this.title2 = this._nodeTab.title2.getComponent(Label); // 获取虚拟列表组件 if (this.scrollView) { this.scrollViewList = this.scrollView.getComponent(HXZ_ScrollViewList); if (!this.scrollViewList) { logger.warn( "[GirlCollectionPanel] content 父节点缺少 HXZ_ScrollViewList 组件,请在编辑器中添加" ); } else { logger.log("[GirlCollectionPanel] 虚拟列表组件初始化成功"); } } this.refresh(); } async refresh() { logger.log("[GirlCollectionPanel] 开始刷新收藏列表"); // 获取收藏数据 const girlData = DataManager.I.getDataById(DataId.Girl); // 获取按时间排序的收藏ID列表(最新的在前) this.cachedBookmarkIds = girlData.getAllBookmarkGirlIdsSortedByTime(); logger.log( `[GirlCollectionPanel] 收藏列表共 ${this.cachedBookmarkIds.length} 项` ); // 更新标题为"我的收藏" // TODO: 可以使用多语言key替换 // 使用虚拟列表:设置总数量,触发自动渲染 if (this.scrollViewList) { this.scrollViewList.numItems = this.cachedBookmarkIds.length; logger.log( `[GirlCollectionPanel] 虚拟列表 numItems 已设置为 ${this.cachedBookmarkIds.length}` ); } else { logger.warn( "[GirlCollectionPanel] scrollViewList 未初始化,无法显示列表" ); } } /** * 虚拟列表渲染回调 * 该方法需要在 Cocos Creator 编辑器中配置到 HXZ_ScrollViewList 的 renderEvent * @param itemNode 虚拟列表传入的节点 * @param index 数据索引 */ onRenderCollectionItem(itemNode: Node, index: number): void { if (index < this.cachedBookmarkIds.length) { const girlId = this.cachedBookmarkIds[index]; const item = itemNode.getComponent(GirlListItem); if (!item) { logger.error( `[GirlCollectionPanel] 节点缺少 GirlListItem 组件,index: ${index}` ); return; } // 获取女孩的分类 const girlData = DataManager.I.getDataById(DataId.Girl); const category = girlData.getGrilCategoryById(girlId); if (category === 0) { logger.warn( `[GirlCollectionPanel] 无法获取 girlId=${girlId} 的分类信息` ); return; } // 刷新数据 item.refreshData(category, girlId, this); itemNode.active = true; logger.log( `[GirlCollectionPanel] 渲染 item: index=${index}, girlId=${girlId}, category=${category}` ); } } private addSlideInAnimation(itemNode: Node, index: number) { // 保存节点的目标位置 const targetPosition = itemNode.getPosition(); // 设置初始位置为屏幕右侧外(偏移300像素) const startPosition = new Vec3( targetPosition.x + 300, targetPosition.y, targetPosition.z ); itemNode.setPosition(startPosition); // 添加递进延时,每个item延迟0.05秒 const delay = index * 0.05; // 执行滑入动画 tween(itemNode) .delay(delay) .to(0.4, { position: targetPosition }, { easing: "cubicOut" }) .start(); } hide() { this.node.active = false; } private registerListener() { GButton.BandClick(this._nodeTab.ReturnBtn, this.Return, this); } Return() { NavigationManager.Instance.closeSubPanel(this); } onDestroy() { // 虚拟列表会自动管理对象池,只需清理数据缓存 this.cachedBookmarkIds = []; logger.log("[GirlCollectionPanel] 组件已销毁"); } }