"use strict"; cc._RF.push(module, '214a9FAXt5FTpkEEnLj0wMq', 'common_scrollview_single'); // Scripts/common/common_scrollview_single.js "use strict"; // -------------------------------------------------------------------- // @author: shiraho@syg.com(必填, 创建模块的人员) // @description: // 新版本无限循环列表容器, cellitem 需要继承basepanel //
Create: new Date().toISOString() // -------------------------------------------------------------------- var CommonScrollViewSingle = cc.Class({ "extends": BaseClass, ctor: function ctor() { this.initConfig(); }, initConfig: function initConfig() { this.parent = null; this.prefabPath = PathTool.getPrefabPath("common", "common_scroll_view"); this.pos = cc.v2(0, 0); this.dir = ScrollViewDir.vertical; this.start_pos = ScrollViewStartPos.top; this.size = cc.size(100, 100); this.ap = cc.v2(0, 0); //存放所有格子结构体 this.cellList = []; //缓存Cell所用到的对象 this.cacheList = {}; //记录活跃得格子ID this.activeCellIdx = {}; //当前选择物品的索引 this.selectCellIndex = 1; //回调方法 this.handler = {}; //到时间显示的索引 this.time_show_index = 0; //是否初始化 this.is_first_init = true; //最大条目 this.cacheMaxSize = 1; }, /** * 创建 * @param {*} parent 所在父节点 * @param {*} pos 滑动组件位置 * @param {*} dir 滑动对齐方式 * @param {*} start_pos 滑动列表开始位置 * @param {*} size 滑动框大小 * @param {*} setting 设置信息 * @param {*} ap 锚点 */ createScroll: function createScroll(parent, pos, dir, start_pos, size, setting, ap) { this.parent = parent; this.pos = pos || cc.v2(0, 0); this.dir = dir || ScrollViewDir.vertical; this.start_pos = start_pos || ScrollViewStartPos.top; this.size = size || cc.size(100, 100); this.ap = ap || cc.v2(0, 0); this.analysisSetting(setting); LoaderManager.getInstance().loadRes(this.prefabPath, function (res_object) { var scroll = res_object; this.createRootWnd(scroll); }.bind(this)); }, //解析数据 analysisSetting: function analysisSetting(setting) { this.setting = setting || {}; this.start_x = this.setting.start_x || 0; //第一个单元的起点X this.space_x = this.setting.space_x || 0; // 横向间隔空间 this.start_y = this.setting.start_y || 0; // 第一个单元的起点Y this.space_y = this.setting.space_y || 0; // 竖向间隔空间 this.item_width = this.setting.item_width || 115; // 单元的宽度 this.item_height = this.setting.item_height || 115; // 单元的高度 this.row = this.setting.row || 5; // 行数,作用于水平方向的滚动 this.col = this.setting.col || 5; // 列数,作用于垂直方向的滚动 this.delay = this.setting.delay || 4; // 创建延迟时间 this.once_num = this.setting.once_num || 1; // 每次创建的数量 this.need_dynamic = this.setting.need_dynamic || true; // 是否需要动态创建的 //横向的只支持一行的.. if (this.dir == ScrollViewDir.horizontal) { this.row = 1; } this.calculationMaxSum(); }, //计算一下一屏最多创建的个数 calculationMaxSum: function calculationMaxSum() { var max_sum; if (this.dir == ScrollViewDir.horizontal) { max_sum = (Math.ceil(this.size.width / (this.item_width + this.space_x)) + 1) * this.row; } else { max_sum = (Math.ceil(this.size.height / (this.item_height + this.space_y)) + 1) * this.col; } this.cacheMaxSize = max_sum; }, // 初始化创建对象 createRootWnd: function createRootWnd(scroll) { this.root_wnd = scroll; this.scroll_view = scroll.getChildByName("ScrollView"); this.scroll_view_mask = this.scroll_view.getChildByName("view"); this.scroll_view_con = this.scroll_view_mask.getChildByName("content"); this.root_wnd.setContentSize(this.size); this.root_wnd.setAnchorPoint(this.ap.x, this.ap.y); this.root_wnd.setPosition(this.pos); this.scroll_view.setContentSize(this.size); this.scroll_view_mask.setContentSize(this.size); this.scroll_view_con.setContentSize(this.size); // 滚动组建 this.scroll_view_compend = this.scroll_view.getComponent(cc.ScrollView); if (this.dir == ScrollViewDir.vertical) { this.scroll_view_compend.vertical = true; } else { this.scroll_view_compend.horizontal = true; } this.container = this.scroll_view_con; if (this.parent) { this.parent.addChild(scroll); } // 监听事件 this.setInnerContainer(); this.registerEvent(); // if (this.select_index != null) { this.reloadData(this.select_index, this.setting); // } }, // 滚动设置 registerEvent: function registerEvent() { if (this.need_dynamic == true) { this.scroll_view_compend.node.on('scrolling', this.checkRectIntersectsRect, this); // this.scroll_view_compend.node.on('bounce-bottom', this.scrollToBottom_callback, this); } }, // 滚动到底部的时候回调 addScrollToBottomCallBack: function addScrollToBottomCallBack(callback) { this.scrollToBottom_callback = callback; }, // 注册事件 registerScriptHandlerSingle: function registerScriptHandlerSingle(func, handlerId) { this.handler[handlerId] = func; }, //获取cell数量 numberOfCells: function numberOfCells() { if (this.handler[ScrollViewFuncType.NumberOfCells]) { return this.handler[ScrollViewFuncType.NumberOfCells](); } }, // 刷新每一个cell updateCellByIndex: function updateCellByIndex(cell, index) { if (this.handler[ScrollViewFuncType.UpdateCellByIndex]) { this.handler[ScrollViewFuncType.UpdateCellByIndex](cell, index); } }, // 创建一个显示对象 createNewCell: function createNewCell() { if (this.handler[ScrollViewFuncType.CreateNewCell]) { return this.handler[ScrollViewFuncType.CreateNewCell](this.item_width, this.item_height); } }, // 点击单个 onCellTouched: function onCellTouched(cell, index) { if (this.handler[ScrollViewFuncType.OnCellTouched]) { this.handler[ScrollViewFuncType.OnCellTouched](cell, index); } }, // 设置是否可点击 setClickEnabled: function setClickEnabled(status) {}, // 设置是否吞噬点击 setSwallowTouches: function setSwallowTouches(status) {}, // 移动过程中是否不再可是范围,不再的时候移除,放到对象池,准备下一次创建 checkRectIntersectsRect: function checkRectIntersectsRect() { if (this.dir == ScrollViewDir.vertical) { this.checkOverShowByVertical(); } else { this.checkOverShowByHorizontal(); } }, // 竖直方向的监测判断 checkOverShowByVertical: function checkOverShowByVertical() { if (this.cellList == null) return; var sum = this.cellList.length; if (sum == 0) return; var container_y = this.container.y; var bot = -container_y; var top = this.size.height + bot; var col_count = Math.ceil(sum / this.col); // 活跃cell开始行数 var activeCellStartRow = 0; for (var i = 0; i < col_count; i++) { var index = i * this.col; var cell = this.cellList[index]; activeCellStartRow = i; if (cell && cell.y - this.item_height * 0.5 <= top) { break; } } // 活跃cell结束行数 var activeCellEndRow = col_count; if (bot > 0) { for (var _i = activeCellStartRow; _i < col_count; _i++) { var index = _i * this.col; var cell = this.cellList[index]; if (cell && cell.y + this.item_height * 0.5 < bot) { activeCellEndRow = _i - 1; break; } } } // 重复使用 var max_count = this.numberOfCells(); for (var _i2 = 0; _i2 < col_count; _i2++) { if (_i2 >= activeCellStartRow && _i2 <= activeCellEndRow) { for (var m = 0; m < this.col; m++) { var index = _i2 * this.col + m; if (!this.activeCellIdx[index]) { if (index <= max_count) { this.updateCellAtIndex(index); this.activeCellIdx[index] = true; } } } } else { for (var _m = 0; _m < this.col; _m++) { var index = _i2 * this.col + _m; if (index <= max_count) { this.activeCellIdx[index] = false; } } } } }, // 竖直方向的监测判断 checkOverShowByVerticalBottom: function checkOverShowByVerticalBottom() { if (this.cellList == null) return; var sum = this.cellList.length; if (sum == 0) return; var container_y = this.container.y; var bot = -container_y; var top = this.size.height + bot; var col_count = Math.ceil(sum / this.col); // 活跃cell开始行数 var activeCellStartRow = col_count; for (var i = col_count - 1; i >= 0; i--) { var index = i * this.col; var cell = this.cellList[index]; activeCellStartRow = i; if (cell && cell.y - this.item_height * 0.5 <= top) { break; } } // 活跃cell结束行数 var activeCellEndRow = 0; if (bot > 0) { for (var _i3 = activeCellStartRow - 1; _i3 >= 0; _i3--) { var index = _i3 * this.col; var cell = this.cellList[index]; if (cell && cell.y + this.item_height * 0.5 < bot) { activeCellEndRow = _i3 + 1; break; } } } // 重复使用 var max_count = this.numberOfCells(); for (var _i4 = 0; _i4 < col_count; _i4++) { if (_i4 <= activeCellStartRow && _i4 >= activeCellEndRow) { for (var m = 0; m < this.col; m++) { var index = _i4 * this.col + m; if (!this.activeCellIdx[index]) { if (index <= max_count) { this.updateCellAtIndex(index); this.activeCellIdx[index] = true; } } } } else { for (var _m2 = 0; _m2 < this.col; _m2++) { var index = _i4 * this.col + _m2; if (index <= max_count) { this.activeCellIdx[index] = false; } } } } }, // 水平方向的监测 checkOverShowByHorizontal: function checkOverShowByHorizontal() { if (this.cellList == null) return; var row_count = this.cellList.length; if (row_count == 0) return; var container_x = this.container.x; var top = -container_x; var bot = top + this.size.width; // 活跃cell开始列数 var activeCellStartRow = 0; if (top > 0) { for (var i = 0; i < row_count; i++) { var cell = this.cellList[i]; activeCellStartRow = i; if (cell && cell.x + this.item_width * 0.5 >= top) { break; } } } // 活跃cell结束行数 var activeCellEndRow = row_count; for (var index = activeCellStartRow; index < row_count; index++) { var cell = this.cellList[index]; if (cell && cell.x - this.item_width * 0.5 > bot) { activeCellEndRow = index; break; } } var max_count = this.numberOfCells(); for (var _index = 0; _index < row_count; _index++) { if (_index >= activeCellStartRow && _index <= activeCellEndRow) { if (!this.activeCellIdx[_index]) { if (_index <= max_count) { this.updateCellAtIndex(_index); this.activeCellIdx[_index] = true; } } } else { if (_index <= max_count) { this.activeCellIdx[_index] = false; } } } }, // 移动到具体位置,暂时不用了 updateMove: function updateMove(pos) {// var target_pos = this.checkPosition(pos.x, pos.y); // var move_to = cc.moveTo(0.1, target_pos.x, target_pos.y).easing(cc.easeBackOut()); // this.container.runAction(move_to); }, // 跳转到指定位置,暂时不用了 jumpToMove: function jumpToMove(pos, time, callback) {}, // 监测位置,暂时也不用了 checkPosition: function checkPosition() {// var _x = this.container.x; // var _y = this.container.y; // if (this.dir == ScrollViewDir.horizontal) { // _x = _x + x; // } else if (this.dir == ScrollViewDir.vertical) { // _y = _y + y; // } // if (_x > 0) { // _x = 0; // } else if (_x < this.size.width - this.container_size.width) { // _x = this.size.width - this.container_size.width; // } // if (_y > 0) { // _y = 0; // } else if (_y < this.size.height - this.container_size.height) { // _y = this.size.height - this.container_size.height; // } // return cc.v2(_x, _y) }, // 获取当前容器的坐标,暂时不用 getCurContainerPosY: function getCurContainerPosY() {}, // 当前容器的坐标 位置 getCurContainerPosX: function getCurContainerPosX() {}, //设置滚动容器的大小 setInnerContainer: function setInnerContainer() { var size = this.numberOfCells(); var container_width = this.size.width; var container_height = this.size.height; var num = 0; if (this.dir == ScrollViewDir.horizontal) { num = Math.ceil(size / this.row); container_width = num * this.item_width + 2 * this.start_x + (num - 1) * this.space_x; } else { num = Math.ceil(size / this.col); container_height = num * this.item_height + 2 * this.start_y + (num - 1) * this.space_y; } container_width = Math.max(container_width, this.size.width); container_height = Math.max(container_height, this.size.height); this.container_size = cc.size(container_width, container_height); if (this.scroll_view_con) { this.scroll_view_con.setContentSize(this.container_size); } if (this.scroll_view_compend) { this.scroll_view_compend.stopAutoScroll(); if (this.start_pos == ScrollViewStartPos.top) { this.scroll_view_compend.scrollToTop(0); } else if (this.start_pos == ScrollViewStartPos.bottom) { this.scroll_view_compend.scrollToBottom(0); } } }, // 刷新当前显示item数据(不改变任何位置的) resetCurrentItems: function resetCurrentItems() { for (var key in this.activeCellIdx) { if (this.activeCellIdx[key] == true) { this.updateCellAtIndex(key); } } }, // 根据index刷新对应的索引,如果在可视范围以内 resetItemByIndex: function resetItemByIndex(index) { if (this.activeCellIdx[index] == true) { this.updateCellAtIndex(index); } }, // 获取所有活跃的cell对象 getActiveCellList: function getActiveCellList() { var list = []; for (var key in this.activeCellIdx) { if (this.activeCellIdx[key] == true) { if (this.cellList[key] && this.cellList[key].cell) { list.push(this.cellList[key].cell); } } } return list; }, // 根据下表获取对应的cell,不管是否活跃 getCellByIndex: function getCellByIndex(index) { if (this.cellList[index] && this.cellList[index].cell) { return this.cellList[index].cell; } }, // 根据下表获取对应的cell的XY位置,先预留 getCellXYByIndex: function getCellXYByIndex(index) {}, // 设置数据 reloadData: function reloadData(select_index, setting) { if (this.root_wnd == null) { this.select_index = select_index; this.setting = setting; return; } if (setting) { this.analysisSetting(setting); } this.cellList = []; this.activeCellIdx = {}; for (var key in this.cacheList) { var _cell = this.cacheList[key]; _cell.setPosition(-10000, 0); } this.setInnerContainer(); var number = this.numberOfCells(); if (number == 0) return; for (var i = 0; i < number; i++) { var cell = null; if (i <= this.time_show_index) { cell = this.getCacheCellByIndex(i); } var row_count = this.cellList.length; var xy = this.getCellPosition(row_count); //row_cont + 1 var cellData = { cell: cell, x: xy.x, y: xy.y }; this.cellList.push(cellData); } if (this.is_first_init) { this.startTimeTicket(); } else { //如果时间显示索引小于总数 应该显示继续当前定时器 让下面的能显示出来 if (this.time_show_index <= number) { this.startTimeTicket(); } } if (select_index == null) { var maxRefreshNum = 0; if (this.dir == ScrollViewDir.horizontal) { maxRefreshNum = this.cacheMaxSize - this.row; } else { maxRefreshNum = this.cacheMaxSize - this.col; } var refreshNum = number < maxRefreshNum ? number : maxRefreshNum; for (var _i5 = 0; _i5 < refreshNum; _i5++) { if (_i5 < this.time_show_index) { //i<= this.updateCellAtIndex(_i5); } this.activeCellIdx[_i5] = true; } } else { this.selectCellByIndex(select_index); } }, // 选中index索引对象(如果列表允许 会排序在开始第一位) selectCellByIndex: function selectCellByIndex(index) { var maxRefreshNum = 0; if (this.dir == ScrollViewDir.horizontal) { maxRefreshNum = this.cacheMaxSize - this.row; } else { maxRefreshNum = this.cacheMaxSize - this.col; } var number = this.numberOfCells(); if (number < maxRefreshNum) { // 不够现实一屏幕 for (var i = 0; i < number; i++) { if (i < this.time_show_index) { //i<= this.updateCellAtIndex(i); } this.activeCellIdx[i] = true; } } else { if (this.dir == ScrollViewDir.horizontal) { var container_x = 0; if (index == 0) { container_x = 0; } else { container_x = -(this.cellList[index].x - (this.item_width + this.space_x) * 0.5); } // 容器X方向最大位置 var max_contariner_x = -(this.container_size.width - this.size.width); if (container_x < max_contariner_x) { container_x = max_contariner_x; } var show_index = Math.floor(Math.abs(container_x) / this.item_width); //+1 if (this.time_show_index < show_index) { this.time_show_index = show_index; } this.container.x = container_x; this.checkOverShowByHorizontal(); } else { var container_y = 0; if (index == 0) { container_y = this.start_y + this.cellList[index].y + this.item_height * 0.5 - this.size.height; } else { container_y = this.cellList[index].y + (this.item_height + this.space_y) * 0.5 - this.size.height; } if (container_y < 0) { container_y = 0; } var index_1 = Math.floor((this.container_size.height - (container_y + this.size.height)) / this.item_height) + 1; var show_index = (index_1 - 1) * this.col; //+1 if (this.time_show_index < show_index) { this.time_show_index = show_index; } this.container.y = -container_y; this.checkOverShowByVertical(); } } if (index >= 0 && index < this.numberOfCells()) { //index>0 and index <= var cell = this.getCacheCellByIndex(index); cell.index = index; this.cellList[index].cell = cell; this.onCellTouched(cell, index); } }, // 定时器创建 startTimeTicket: function startTimeTicket() { if (this.time_tichet == null) { if (this.cellList.length == 0) return; // 到时间现实索引 var once_num = this.once_num || 1; var _callback = function () { if (this.container == null) return; var count = this.time_show_index + once_num; var index = this.time_show_index; // if(index == 0){ // index = 1; // } var size = this.cellList.length; this.time_show_index = this.time_show_index + once_num; for (var i = index; i < count; i++) { if (i > size) break; var cellData = this.cellList[i]; if (cellData && cellData.cell == null) { cellData.cell = this.getCacheCellByIndex(i); } if (this.activeCellIdx[i]) { this.updateCellAtIndex(i); } } if (this.time_show_index >= size) { this.clearTimeTicket(); this.is_first_init = false; } }.bind(this); this.time_tichet = gcore.Timer.set(function () { _callback(); }.bind(this), this.delay / 60, -1); } }, // 清除掉定时器 clearTimeTicket: function clearTimeTicket() { if (this.time_tichet) { gcore.Timer.del(this.time_tichet); this.time_tichet = null; } }, // 获取index的对应位置 getCellPosition: function getCellPosition(index) { var ap_x = 0.5; var ap_y = 0.5; var _x = 0; var _y = 0; if (this.dir == ScrollViewDir.horizontal) { _x = this.start_x + this.item_width * ap_x + (this.item_width + this.space_x) * Math.floor(index / this.row); _y = this.container_size.height - (this.start_y + this.item_height * ap_y + index % this.row * (this.item_height + this.space_y)); } else { if (this.start_pos == ScrollViewStartPos.top) { _x = this.start_x + this.item_width * ap_x + (this.item_width + this.space_x) * (index % this.col); _y = this.container_size.height - (this.start_y + this.item_height * ap_y + Math.floor(index / this.col) * (this.item_height + this.space_y)); } else { _x = this.start_x + this.item_width * ap_x + (this.item_width + this.space_x) * (index % this.col); _y = this.start_y + this.item_height * ap_y + Math.floor(index / this.col) * (this.item_height + this.space_y); } } return { x: _x, y: _y }; }, // 获取格子下表对应的缓存itemcell getCacheCellByIndex: function getCacheCellByIndex(index) { var cacheIndex = index % this.cacheMaxSize; if (this.cacheList[cacheIndex] == null) { var newCell = this.createNewCell(); if (newCell) { // newCell.setAnchorPoint(0.5, 0.5;) newCell.setPosition(-10000, 0); this.cacheList[cacheIndex] = newCell; newCell.setParent(this.container); } return newCell; } else { return this.cacheList[cacheIndex]; } }, // 更新格子,并标记活跃 updateCellAtIndex: function updateCellAtIndex(index) { if (index > this.time_show_index) return; if (this.cellList[index] == null) return; var cellData = this.cellList[index]; if (cellData.cell == null) { cellData.cell = this.getCacheCellByIndex(index); } cellData.cell.setPosition(cellData.x, cellData.y); this.updateCellByIndex(cellData.cell, index); }, // getMaxSize: function getMaxSize() { return this.container_size; }, getContainer: function getContainer() { return this.container; }, deleteMe: function deleteMe() { this.DeleteMe(); }, setVisible: function setVisible(bool) { if (this.root_wnd && bool != null) { this.root_wnd.active = bool; } }, DeleteMe: function DeleteMe() { this.clearTimeTicket(); for (var key in this.cacheList) { var item = this.cacheList[key]; if (item && item.deleteMe) { item.deleteMe(); } item = null; } this.cellList = null; this.cacheList = null; this.activeCellIdx = null; this.root_wnd.destroy(); this.root_wnd = null; LoaderManager.getInstance().releasePrefab(this.prefabPath); } }); cc._RF.pop();