Files
18xchat/.svn/pristine/34/34e9ca1b25f327a60793407d2dee3655c8908181.svn-base
2025-07-17 17:18:21 +08:00

1534 lines
62 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { _decorator, ScrollView, Node, Prefab, Enum, Component, EventHandler, Layout, NodePool, Size, instantiate, size, Widget, v3, UITransform, v2, tween } from "cc";
import li_Component from "./li_Component";
import ScrollviewListItem from "./ScrollviewListItem";
import Utils from "./Utils";
const { ccclass, property, disallowMultiple, menu, executionOrder, requireComponent } = _decorator;
enum TemplateType {
NODE = 1,
PREFAB = 2,
}
//滑动列表组件
@ccclass
@disallowMultiple()
@menu('自定义控件/ScrollViewList')
@requireComponent(ScrollView)
//脚本生命周期回调的执行优先级。小于 0 的脚本将优先执行,大于 0 的脚本将最后执行。该优先级只对 onLoad, onEnable, start, update 和 lateUpdate 有效,对 onDisable 和 onDestroy 无效。
@executionOrder(-4000)
export default class ScrollViewList extends li_Component {
//模板类型
@property({
type: Enum(TemplateType),
tooltip: '模板类型 Node或者Prefab',
})
private templateType: TemplateType = TemplateType.NODE;
//模板ItemNode
@property({
type: Node,
tooltip: '模板Item',
visible() { return this.templateType == TemplateType.NODE; }
})
tmpNode: Node = null;
//模板ItemPrefab
@property({
type: Prefab,
tooltip: '模板Item',
visible() { return this.templateType == TemplateType.PREFAB; }
})
tmpPrefab: Prefab = null;
//渲染事件(渲染器)
@property({
type: EventHandler,
tooltip: '渲染事件(渲染器)',
})
private renderEvent: EventHandler = new EventHandler();
//滚动结束触发事件
@property({
type: EventHandler,
tooltip: '滚动结束时触发事件',
})
private renderEventUpData: EventHandler = new EventHandler();
//当前选择id
private _virtual: boolean = true;//是否为虚拟列表(动态列表)
private _selectedId: number = -1;
private _lastSelectedId: number;
private multSelected: number[];
private _forceUpdate: boolean = false;
private _align: number;
private _horizontalDir: number;
private _verticalDir: number;
private _startAxis: number;
private _alignCalcType: number;
public content: Node;
private contentUITF: UITransform;
private firstListId: number;
public displayItemNum: number;
private _updateDone: boolean = true;
private _updateCounter: number;
public _actualNumItems: number;
private _cyclicNum: number;
private _cyclicPos1: number;
private _cyclicPos2: number;
//列表数量
@property({
serializable: false
})
private _numItems: number = 0;
set numItems(val: number) {
if (!this.checkInited(false))
return;
if (val == null || val < 0) {
//hg_utils.hgLog('numItems set the wrong::', val);
return;
}
this._actualNumItems = this._numItems = val;
this._forceUpdate = true;
if (this._virtual) {
this._resizeContent();
this._onScrolling();
} else {
let layout: Layout = this.content.getComponent(Layout);
if (layout) {
layout.enabled = true;
}
this._delRedundantItem();
this.firstListId = 0;
for (let n: number = 0; n < val; n++) {
this._createOrUpdateItem2(n);
}
this.displayItemNum = val;
}
}
get numItems() {
return this._actualNumItems;
}
private _inited: boolean = false;
private _scrollView: ScrollView;
get scrollView() {
return this._scrollView;
}
private _uitf: UITransform;
private _layout: Layout;
private _resizeMode//: Layout.ResizeMode;
private _topGap: number;
private _rightGap: number;
private _bottomGap: number;
private _leftGap: number;
private _columnGap: number;
private _lineGap: number;
private _colLineNum: number;
private _lastDisplayData: number[];
public displayData: any[];
private _pool: NodePool;
private _itemTmp: Node;
private _needUpdateWidget: boolean = false;
private _itemSize: Size;
private _sizeType: boolean;
public _customSize: any;
private frameCount: number;
private _aniDelRuning: boolean = false;
private viewTop: number;
private viewRight: number;
private viewBottom: number;
private viewLeft: number;
private _doneAfterUpdate: boolean = false;
private elasticTop: number;
private elasticRight: number;
private elasticBottom: number;
private elasticLeft: number;
private scrollToListId: number;
private adhering: boolean = false;
private _adheringBarrier: boolean = false;
private nearestListId: number;
public curPageNum: number = 0;
private _beganPos: number;
private _scrollPos: number;
private _scrollToListId: number;
private _scrollToEndTime: number;
private _scrollToSo: any;
private _lack: boolean;
private _allItemSize: number;
private _allItemSizeNoEdge: number;
private _scrollItem: any;//当前控制 ScrollView 滚动的 Item
set TopGap(val: number) {
this._topGap = val
}
//----------------------------------------------------------------------------
onLoad() {
this._init();
}
onNodeDestroy() {
if (this._itemTmp && this._itemTmp.isValid)
this._itemTmp.destroy();
if (this.tmpNode && this.tmpNode.isValid)
this.tmpNode.destroy();
while (this._pool && this._pool.size()) {
let node = this._pool.get();
node.destroy();
}
}
onEnable() {
this._registerEvent();
this._init();
}
onDisable() {
this._unregisterEvent();
}
//注册事件
_registerEvent() {
this.node.on("touch-start", this._onTouchStart, this);
this.node.on("touch-end", this._onTouchUp, this);
this.node.on("touch-cancel", this._onTouchCancelled, this);
this.node.on("scroll-began", this._onScrollBegan, this);
this.node.on("scroll-ended", this._onScrollEnded, this);
this.node.on("scrolling", this._onScrolling, this);
this.node.on("size-changed", this._onSizeChanged, this);
}
//卸载事件
_unregisterEvent() {
this.node.off("touch-start", this._onTouchStart, this);
this.node.off("touch-end", this._onTouchUp, this);
this.node.off("touch-cancel", this._onTouchCancelled, this);
this.node.off("scroll-began", this._onScrollBegan, this);
this.node.off("scroll-ended", this._onScrollEnded, this);
this.node.off("scrolling", this._onScrolling, this);
this.node.off("size-changed", this._onSizeChanged, this);
}
//初始化各种..
_init() {
if (this._inited)
return;
if (this.tmpPrefab == null && this.tmpNode == null)
return;
this._scrollView = this.node.getComponent(ScrollView);
this.content = this._scrollView.content;
if (!this.content) {
//hg_utils.hgLog(this.node.name + "'s ScrollView unset content!");
return;
}
this.contentUITF = this.content.getComponent(UITransform);
this._uitf = this.node.getComponent(UITransform);
this._layout = this.content.getComponent(Layout);
this._align = this._layout.type; //排列模式
this._resizeMode = this._layout.resizeMode; //自适应模式
this._startAxis = this._layout.startAxis;
this._topGap = this._layout.paddingTop; //顶边距
this._rightGap = this._layout.paddingRight; //右边距
this._bottomGap = this._layout.paddingBottom; //底边距
this._leftGap = this._layout.paddingLeft; //左边距
this._columnGap = this._layout.spacingX; //列距
this._lineGap = this._layout.spacingY; //行距
this._colLineNum; //列数或行数(非GRID模式则=1,表示单列或单行);
this._verticalDir = this._layout.verticalDirection; //垂直排列子节点的方向
this._horizontalDir = this._layout.horizontalDirection; //水平排列子节点的方向
this.setTemplateItem(instantiate(this.templateType == TemplateType.PREFAB ? this.tmpPrefab : this.tmpNode));
this._lastDisplayData = []; //最后一次刷新的数据
this.displayData = []; //当前数据
while (this._pool && this._pool.size()) {
let node = this._pool.get();
node.destroy();
}
this._pool = new NodePool(); //这是个池子..
this._forceUpdate = false; //是否强制更新
this._updateCounter = 0; //当前分帧渲染帧数
this._updateDone = true; //分帧渲染是否完成
this.curPageNum = 0; //当前页数
switch (this._align) {
case Layout.Type.HORIZONTAL: {
switch (this._horizontalDir) {
case Layout.HorizontalDirection.LEFT_TO_RIGHT:
this._alignCalcType = 1;
break;
case Layout.HorizontalDirection.RIGHT_TO_LEFT:
this._alignCalcType = 2;
break;
}
break;
}
case Layout.Type.VERTICAL: {
switch (this._verticalDir) {
case Layout.VerticalDirection.TOP_TO_BOTTOM:
this._alignCalcType = 3;
break;
case Layout.VerticalDirection.BOTTOM_TO_TOP:
this._alignCalcType = 4;
break;
}
break;
}
case Layout.Type.GRID: {
switch (this._startAxis) {
case Layout.AxisDirection.HORIZONTAL:
switch (this._verticalDir) {
case Layout.VerticalDirection.TOP_TO_BOTTOM:
this._alignCalcType = 3;
break;
case Layout.VerticalDirection.BOTTOM_TO_TOP:
this._alignCalcType = 4;
break;
}
break;
case Layout.AxisDirection.VERTICAL:
switch (this._horizontalDir) {
case Layout.HorizontalDirection.LEFT_TO_RIGHT:
this._alignCalcType = 1;
break;
case Layout.HorizontalDirection.RIGHT_TO_LEFT:
this._alignCalcType = 2;
break;
}
break;
}
break;
}
}
this.content.removeAllChildren();
this._inited = true;
}
/**
* 为了实现循环列表,必须覆写ScrollView的某些函数
* @param {Number} dt
*/
_processAutoScrolling(dt: number) {
let brakingFactor: number = 1;
this._scrollView['_autoScrollAccumulatedTime'] += dt * (1 / brakingFactor);
let percentage: number = Math.min(1, this._scrollView['_autoScrollAccumulatedTime'] / this._scrollView['_autoScrollTotalTime']);
if (this._scrollView['_autoScrollAttenuate']) {
let time: number = percentage - 1;
percentage = time * time * time * time * time + 1;
}
let astdelta = this._scrollView['_autoScrollTargetDelta']//.mul(percentage)
let newDeltav3 = v3(astdelta.x*percentage, astdelta.y*percentage, astdelta.z*percentage)
let newPosition: any = this._scrollView['_autoScrollStartPosition'].add(newDeltav3);
let EPSILON: number = this._scrollView['getScrollEndedEventTiming']();
let reachedEnd: boolean = Math.abs(percentage - 1) <= EPSILON;
let fireEvent: boolean = Math.abs(percentage - 1) <= this._scrollView['getScrollEndedEventTiming']();
if (fireEvent && !this._scrollView['_isScrollEndedWithThresholdEventFired']) {
this._scrollView['_dispatchEvent']('scroll-ended-with-threshold');
this._scrollView['_isScrollEndedWithThresholdEventFired'] = true;
}
if (reachedEnd) {
this._scrollView['_autoScrolling'] = false;
}
let deltaMove: any = newPosition.sub(this._scrollView.content.getPosition()); //断点
// this._scrollView['_moveContent'](this._scrollView['_clampDelta'](deltaMove), reachedEnd);
this._scrollView['_dispatchEvent'](ScrollView.EventType.SCROLLING);
if (!this._scrollView['_autoScrolling']) {
this._scrollView['_isBouncing'] = false;
this._scrollView['_scrolling'] = false;
this._scrollView['_dispatchEvent'](ScrollView.EventType.SCROLL_ENDED);
}
}
//设置模板Item
setTemplateItem(item: any) {
if (!item)
return;
if (this.tmpNode == null && this.tmpPrefab == null) {
if (item instanceof Prefab) {
this.templateType = TemplateType.PREFAB;
this.tmpPrefab = item;
} else if (item instanceof Node) {
this.templateType = TemplateType.NODE;
this.tmpNode = item;
}
this._init();
return;
}
this._itemTmp = item;
if (this._resizeMode == Layout.ResizeMode.CHILDREN){
this._itemSize = this._layout.cellSize;
}
else{
let uitf = item.getComponent(UITransform)
this._itemSize = size(uitf.width, uitf.height);
}
//获取ListItem,如果没有就取消选择模式
let com = item.getComponent(ScrollviewListItem);
let remove = false;
if (!com)
remove = true;
com = item.getComponent(Widget);
if (com && com.enabled) {
this._needUpdateWidget = true;
}
switch (this._align) {
case Layout.Type.HORIZONTAL:
this._colLineNum = 1;
this._sizeType = false;
break;
case Layout.Type.VERTICAL:
this._colLineNum = 1;
this._sizeType = true;
break;
case Layout.Type.GRID:
switch (this._startAxis) {
case Layout.AxisDirection.HORIZONTAL:
//计算列数
let trimW: number = this.contentUITF.width - this._leftGap - this._rightGap;
this._colLineNum = Math.floor((trimW + this._columnGap) / (this._itemSize.width + this._columnGap));
this._sizeType = true;
break;
case Layout.AxisDirection.VERTICAL:
//计算行数
let trimH: number = this.contentUITF.height - this._topGap - this._bottomGap;
this._colLineNum = Math.floor((trimH + this._lineGap) / (this._itemSize.height + this._lineGap));
this._sizeType = false;
break;
}
break;
}
}
/**
* 检查是否初始化
* @param {Boolean} printLog 是否打印错误信息
* @returns
*/
checkInited(printLog: boolean = true) {
if (!this._inited) {
if (printLog)
//hg_utils.hgLog('List initialization not completed!');
return false;
}
return true;
}
//禁用 Layout 组件,自行计算 Content Size
_resizeContent() {
let result: number;
switch (this._align) {
case Layout.Type.HORIZONTAL: {
if (this._customSize) {
let fixed: any = this._getFixedSize(null);
result = this._leftGap + fixed.val + (this._itemSize.width * (this._numItems - fixed.count)) + (this._columnGap * (this._numItems - 1)) + this._rightGap;
} else {
result = this._leftGap + (this._itemSize.width * this._numItems) + (this._columnGap * (this._numItems - 1)) + this._rightGap;
}
break;
}
case Layout.Type.VERTICAL: {
if (this._customSize) {
let fixed: any = this._getFixedSize(null);
result = this._topGap + fixed.val + (this._itemSize.height * (this._numItems - fixed.count)) + (this._lineGap * (this._numItems - 1)) + this._bottomGap;
} else {
result = this._topGap + (this._itemSize.height * this._numItems) + (this._lineGap * (this._numItems - 1)) + this._bottomGap;
}
break;
}
case Layout.Type.GRID: {
switch (this._startAxis) {
case Layout.AxisDirection.HORIZONTAL:
let lineNum: number = Math.ceil(this._numItems / this._colLineNum);
result = this._topGap + (this._itemSize.height * lineNum) + (this._lineGap * (lineNum - 1)) + this._bottomGap;
break;
case Layout.AxisDirection.VERTICAL:
let colNum: number = Math.ceil(this._numItems / this._colLineNum);
result = this._leftGap + (this._itemSize.width * colNum) + (this._columnGap * (colNum - 1)) + this._rightGap;
break;
}
break;
}
}
if (!this.content) {
return;
}
let layout: Layout = this.content.getComponent(Layout);
if (layout)
layout.enabled = false;
this._allItemSize = result;
this._allItemSizeNoEdge = this._allItemSize - (this._sizeType ? (this._topGap + this._bottomGap) : (this._leftGap + this._rightGap));
this._lack = this._allItemSize < (this._sizeType ? this._uitf.height : this._uitf.width);
let slideOffset: number = .1;
let targetWH: number = this._lack ? ((this._sizeType ? this._uitf.height : this._uitf.width) - slideOffset) : (this._allItemSize);
if (targetWH < 0)
targetWH = 0;
if (this._sizeType) {
this.contentUITF.height = targetWH;
} else {
this.contentUITF.width = targetWH;
}
}
//计算可视范围
_calcViewPos() {
if (!this.content) return;
let scrollPos: any = this.content.getPosition();
switch (this._alignCalcType) {
case 1://单行HORIZONTALLEFT_TO_RIGHT)、网格VERTICALLEFT_TO_RIGHT
this.elasticLeft = scrollPos.x > 0 ? scrollPos.x : 0;
this.viewLeft = (scrollPos.x < 0 ? -scrollPos.x : 0) - this.elasticLeft;
this.viewRight = this.viewLeft + this._uitf.width;
this.elasticRight = this.viewRight > this.contentUITF.width ? Math.abs(this.viewRight - this.contentUITF.width) : 0;
this.viewRight += this.elasticRight;
// //hg_utils.hgLog(this.elasticLeft, this.elasticRight, this.viewLeft, this.viewRight);
break;
case 2://单行HORIZONTALRIGHT_TO_LEFT)、网格VERTICALRIGHT_TO_LEFT
this.elasticRight = scrollPos.x < 0 ? -scrollPos.x : 0;
this.viewRight = (scrollPos.x > 0 ? -scrollPos.x : 0) + this.elasticRight;
this.viewLeft = this.viewRight - this._uitf.width;
this.elasticLeft = this.viewLeft < -this.contentUITF.width ? Math.abs(this.viewLeft + this.contentUITF.width) : 0;
this.viewLeft -= this.elasticLeft;
// //hg_utils.hgLog(this.elasticLeft, this.elasticRight, this.viewLeft, this.viewRight);
break;
case 3://单列VERTICALTOP_TO_BOTTOM)、网格HORIZONTALTOP_TO_BOTTOM
this.elasticTop = scrollPos.y < 0 ? Math.abs(scrollPos.y) : 0;
this.viewTop = (scrollPos.y > 0 ? -scrollPos.y : 0) + this.elasticTop;
this.viewBottom = this.viewTop - this._uitf.height;
this.elasticBottom = this.viewBottom < -this.contentUITF.height ? Math.abs(this.viewBottom + this.contentUITF.height) : 0;
this.viewBottom += this.elasticBottom;
// //hg_utils.hgLog(this.elasticTop, this.elasticBottom, this.viewTop, this.viewBottom);
break;
case 4://单列VERTICALBOTTOM_TO_TOP)、网格HORIZONTALBOTTOM_TO_TOP
this.elasticBottom = scrollPos.y > 0 ? Math.abs(scrollPos.y) : 0;
this.viewBottom = (scrollPos.y < 0 ? -scrollPos.y : 0) - this.elasticBottom;
this.viewTop = this.viewBottom + this._uitf.height;
this.elasticTop = this.viewTop > this.contentUITF.height ? Math.abs(this.viewTop - this.contentUITF.height) : 0;
this.viewTop -= this.elasticTop;
// //hg_utils.hgLog(this.elasticTop, this.elasticBottom, this.viewTop, this.viewBottom);
break;
}
}
//计算位置 根据id
_calcItemPos(id: number) {
let width: number, height: number, top: number, bottom: number, left: number, right: number, itemX: number, itemY: number;
if (!this._itemSize) return {};
switch (this._align) {
case Layout.Type.HORIZONTAL:
switch (this._horizontalDir) {
case Layout.HorizontalDirection.LEFT_TO_RIGHT: {
if (this._customSize) {
let fixed: any = this._getFixedSize(id);
left = this._leftGap + ((this._itemSize.width + this._columnGap) * (id - fixed.count)) + (fixed.val + (this._columnGap * fixed.count));
let cs: number = this._customSize[id];
width = (cs > 0 ? cs : this._itemSize.width);
} else {
left = this._leftGap + ((this._itemSize.width + this._columnGap) * id);
width = this._itemSize.width;
}
right = left + width;
return {
id: id,
left: left,
right: right,
x: left + (this._itemTmp.getComponent(UITransform).anchorX * width),
y: this._itemTmp.position.y,
};
}
case Layout.HorizontalDirection.RIGHT_TO_LEFT: {
if (this._customSize) {
let fixed: any = this._getFixedSize(id);
right = -this._rightGap - ((this._itemSize.width + this._columnGap) * (id - fixed.count)) - (fixed.val + (this._columnGap * fixed.count));
let cs: number = this._customSize[id];
width = (cs > 0 ? cs : this._itemSize.width);
} else {
right = -this._rightGap - ((this._itemSize.width + this._columnGap) * id);
width = this._itemSize.width;
}
left = right - width;
return {
id: id,
right: right,
left: left,
x: left + (this._itemTmp.getComponent(UITransform).anchorX * width),
y: this._itemTmp.position.y,
};
}
}
break;
case Layout.Type.VERTICAL: {
switch (this._verticalDir) {
case Layout.VerticalDirection.TOP_TO_BOTTOM: {
if (this._customSize) {
let fixed: any = this._getFixedSize(id);
top = -this._topGap - ((this._itemSize.height + this._lineGap) * (id - fixed.count)) - (fixed.val + (this._lineGap * fixed.count));
let cs: number = this._customSize[id];
height = (cs > 0 ? cs : this._itemSize.height);
} else {
top = -this._topGap - ((this._itemSize.height + this._lineGap) * id);
height = this._itemSize.height;
}
bottom = top - height;
return {
id: id,
top: top,
bottom: bottom,
x: this._itemTmp.position.x,
y: bottom + (this._itemTmp.getComponent(UITransform).anchorY * height),
};
}
case Layout.VerticalDirection.BOTTOM_TO_TOP: {
if (this._customSize) {
let fixed: any = this._getFixedSize(id);
bottom = this._bottomGap + ((this._itemSize.height + this._lineGap) * (id - fixed.count)) + (fixed.val + (this._lineGap * fixed.count));
let cs: number = this._customSize[id];
height = (cs > 0 ? cs : this._itemSize.height);
} else {
bottom = this._bottomGap + ((this._itemSize.height + this._lineGap) * id);
height = this._itemSize.height;
}
top = bottom + height;
return {
id: id,
top: top,
bottom: bottom,
x: this._itemTmp.position.x,
y: bottom + (this._itemTmp.getComponent(UITransform).anchorY * height),
};
break;
}
}
}
case Layout.Type.GRID: {
let colLine: number = Math.floor(id / this._colLineNum);
switch (this._startAxis) {
case Layout.AxisDirection.HORIZONTAL: {
switch (this._verticalDir) {
case Layout.VerticalDirection.TOP_TO_BOTTOM: {
top = -this._topGap - ((this._itemSize.height + this._lineGap) * colLine);
bottom = top - this._itemSize.height;
itemY = bottom + (this._itemTmp.getComponent(UITransform).anchorY * this._itemSize.height);
break;
}
case Layout.VerticalDirection.BOTTOM_TO_TOP: {
bottom = this._bottomGap + ((this._itemSize.height + this._lineGap) * colLine);
top = bottom + this._itemSize.height;
itemY = bottom + (this._itemTmp.getComponent(UITransform).anchorY * this._itemSize.height);
break;
}
}
itemX = this._leftGap + ((id % this._colLineNum) * (this._itemSize.width + this._columnGap));
switch (this._horizontalDir) {
case Layout.HorizontalDirection.LEFT_TO_RIGHT: {
itemX += (this._itemTmp.getComponent(UITransform).anchorX * this._itemSize.width);
itemX -= (this.contentUITF.anchorX * this.contentUITF.width);
break;
}
case Layout.HorizontalDirection.RIGHT_TO_LEFT: {
itemX += ((1 - this._itemTmp.getComponent(UITransform).anchorX) * this._itemSize.width);
itemX -= ((1 - this.contentUITF.anchorX) * this.contentUITF.width);
itemX *= -1;
break;
}
}
return {
id: id,
top: top,
bottom: bottom,
x: itemX,
y: itemY,
};
}
case Layout.AxisDirection.VERTICAL: {
switch (this._horizontalDir) {
case Layout.HorizontalDirection.LEFT_TO_RIGHT: {
left = this._leftGap + ((this._itemSize.width + this._columnGap) * colLine);
right = left + this._itemSize.width;
itemX = left + (this._itemTmp.getComponent(UITransform).anchorX * this._itemSize.width);
itemX -= (this.contentUITF.anchorX * this.contentUITF.width);
break;
}
case Layout.HorizontalDirection.RIGHT_TO_LEFT: {
right = -this._rightGap - ((this._itemSize.width + this._columnGap) * colLine);
left = right - this._itemSize.width;
itemX = left + (this._itemTmp.getComponent(UITransform).anchorX * this._itemSize.width);
itemX += ((1 - this.contentUITF.anchorX) * this.contentUITF.width);
break;
}
}
itemY = -this._topGap - ((id % this._colLineNum) * (this._itemSize.height + this._lineGap));
switch (this._verticalDir) {
case Layout.VerticalDirection.TOP_TO_BOTTOM: {
itemY -= ((1 - this._itemTmp.getComponent(UITransform).anchorY) * this._itemSize.height);
itemY += ((1 - this.contentUITF.anchorY) * this.contentUITF.height);
break;
}
case Layout.VerticalDirection.BOTTOM_TO_TOP: {
itemY -= ((this._itemTmp.getComponent(UITransform).anchorY) * this._itemSize.height);
itemY += (this.contentUITF.anchorY * this.contentUITF.height);
itemY *= -1;
break;
}
}
return {
id: id,
left: left,
right: right,
x: itemX,
y: itemY,
};
}
}
break;
}
}
}
//计算已存在的Item的位置
_calcExistItemPos(id: number) {
let item: Node = this.getItemByListId(id);
if (!item)
return null;
let data: any = {
id: id,
x: item.position.x,
y: item.position.y,
};
let uitf = item.getComponent(UITransform)
if (this._sizeType) {
data.top = item.position.y + (uitf.height * (1 - uitf.anchorY));
data.bottom = item.position.y - (uitf.height * uitf.anchorY);
} else {
data.left = item.position.x - (uitf.width * uitf.anchorX);
data.right = item.position.x + (uitf.width * (1 - uitf.anchorX));
}
return data;
}
//获取Item位置
getItemPos(id: number) {
return this._calcItemPos(id);
}
//获取固定尺寸
_getFixedSize(listId: number) {
if (!this._customSize)
return null;
if (listId == null)
listId = this._numItems;
let fixed: number = 0;
let count: number = 0;
for (let id in this._customSize) {
if (parseInt(id) < listId) {
fixed += this._customSize[id];
count++;
}
}
return {
val: fixed,
count: count,
};
}
//滚动开始时..
private canRefresh: boolean = false;
_onScrollBegan() {
// Utils.Log("滚动容器 _onScrollBegan")
this.canRefresh = false;
this._beganPos = this._sizeType ? this.viewTop : this.viewLeft;
}
//滚动进行时...
_onScrolling(ev: Event = null) {
// Utils.Log("滚动容器 _onScrolling")
if (!this._inited)
return
if (this.frameCount == null)
this.frameCount = 0;
if (!this._forceUpdate && (ev && ev.type != ScrollView.EventType.SCROLL_ENDED) && this.frameCount > 0) {
this.frameCount--;
return;
} else{
this.frameCount = 0;
}
if (this._aniDelRuning)
return;
let scorv = this.node.getComponent(ScrollView)
let maxPos = scorv.getMaxScrollOffset();
let curPos = scorv.getScrollOffset();
if (scorv.vertical) {
if (curPos.y - maxPos.y > 100) {
this.canRefresh = true;
}
} else if (scorv.horizontal) {
if (curPos.x - maxPos.x > 100) {
this.canRefresh = true;
}
}
this._calcViewPos();
let vTop: number, vRight: number, vBottom: number, vLeft: number;
if (this._sizeType) {
vTop = this.viewTop;
vBottom = this.viewBottom;
} else {
vRight = this.viewRight;
vLeft = this.viewLeft;
}
if (this._virtual) {
this.displayData = [];
let itemPos: any;
let curId: number = 0;
let endId: number = this._numItems - 1;
if (this._customSize) {
let breakFor: boolean = false;
//如果该item的位置在可视区域内,就推入displayData
for (; curId <= endId && !breakFor; curId++) {
itemPos = this._calcItemPos(curId);
switch (this._align) {
case Layout.Type.HORIZONTAL:
if (itemPos.right >= vLeft && itemPos.left <= vRight) {
this.displayData.push(itemPos);
} else if (curId != 0 && this.displayData.length > 0) {
breakFor = true;
}
break;
case Layout.Type.VERTICAL:
if (itemPos.bottom <= vTop && itemPos.top >= vBottom) {
this.displayData.push(itemPos);
} else if (curId != 0 && this.displayData.length > 0) {
breakFor = true;
}
break;
case Layout.Type.GRID:
switch (this._startAxis) {
case Layout.AxisDirection.HORIZONTAL:
if (itemPos.bottom <= vTop && itemPos.top >= vBottom) {
this.displayData.push(itemPos);
} else if (curId != 0 && this.displayData.length > 0) {
breakFor = true;
}
break;
case Layout.AxisDirection.VERTICAL:
if (itemPos.right >= vLeft && itemPos.left <= vRight) {
this.displayData.push(itemPos);
} else if (curId != 0 && this.displayData.length > 0) {
breakFor = true;
}
break;
}
break;
}
}
} else {
if (!this._itemSize) {
return;
}
let ww: number = this._itemSize.width + this._columnGap;
let hh: number = this._itemSize.height + this._lineGap;
switch (this._alignCalcType) {
case 1://单行HORIZONTALLEFT_TO_RIGHT)、网格VERTICALLEFT_TO_RIGHT
curId = (vLeft + this._leftGap) / ww;
endId = (vRight + this._rightGap) / ww;
break;
case 2://单行HORIZONTALRIGHT_TO_LEFT)、网格VERTICALRIGHT_TO_LEFT
curId = (-vRight - this._rightGap) / ww;
endId = (-vLeft - this._leftGap) / ww;
break;
case 3://单列VERTICALTOP_TO_BOTTOM)、网格HORIZONTALTOP_TO_BOTTOM
curId = (-vTop - this._topGap) / hh;
endId = (-vBottom - this._bottomGap) / hh;
break;
case 4://单列VERTICALBOTTOM_TO_TOP)、网格HORIZONTALBOTTOM_TO_TOP
curId = (vBottom + this._bottomGap) / hh;
endId = (vTop + this._topGap) / hh;
break;
}
curId = Math.floor(curId) * this._colLineNum;
endId = Math.ceil(endId) * this._colLineNum;
endId--;
if (curId < 0)
curId = 0;
if (endId >= this._numItems)
endId = this._numItems - 1;
for (; curId <= endId; curId++) {
this.displayData.push(this._calcItemPos(curId));
}
}
this._delRedundantItem();
if (this.displayData.length <= 0 || !this._numItems) { //if none, delete all.
this._lastDisplayData = [];
return;
}
this.firstListId = this.displayData[0].id;
this.displayItemNum = this.displayData.length;
let len: number = this._lastDisplayData.length;
let haveDataChange: boolean = this.displayItemNum != len;
if (haveDataChange) {
// 因List的显示数据是有序的,所以只需要判断数组长度是否相等,以及头、尾两个元素是否相等即可。
haveDataChange = this.firstListId != this._lastDisplayData[0] || this.displayData[this.displayItemNum - 1].id != this._lastDisplayData[len - 1];
}
if (this._forceUpdate || haveDataChange) { //如果是强制更新
//直接渲染
this._lastDisplayData = [];
// //hg_utils.hgLog('List Display Data II::', this.displayData);
for (let c = 0; c < this.displayItemNum; c++) {
this._createOrUpdateItem(this.displayData[c]);
}
this._forceUpdate = false;
}
this._calcNearestItem();
}
}
//滚动结束时..
_onScrollEnded() {
// Utils.Log("滚动容器 _onScrollEnded")
if (this.scrollToListId != null) {
let item: any = this.getItemByListId(this.scrollToListId);
this.scrollToListId = null;
if (item) {
// item.runAction(cc.sequence(
// cc.scaleTo(.1, 1.06),
// cc.scaleTo(.1, 1),
// ));
tween(item)
.to(0.1, {scale: v3(1.06, 1.06, 1.06)})
.to(0.1, {scale: v3(1, 1, 1)})
.start()
}
}
this._onScrolling();
if (this.canRefresh) {
this.canRefresh = false;
Component.EventHandler.emitEvents([this.renderEventUpData]);
}
}
// 触摸时
_onTouchStart(ev, captureListeners) {
// Utils.Log("滚动容器 _onTouchStart")
this.canRefresh = false;
let isMe = ev.eventPhase === Event.AT_TARGET && ev.target === this.node;
if (!isMe) {
let itemNode: any = ev.target;
while (itemNode._listId == null && itemNode.parent)
itemNode = itemNode.parent;
this._scrollItem = itemNode._listId != null ? itemNode : ev.target;
}
}
//触摸抬起时..
_onTouchUp() {
// Utils.Log("滚动容器 _onTouchUp")
this._scrollPos = null;
this._scrollItem = null;
}
_onTouchCancelled(ev, captureListeners) {
// Utils.Log("滚动容器 _onTouchCancelled")
this._scrollPos = null;
this._scrollItem = null;
}
//当尺寸改变
_onSizeChanged() {
// Utils.Log("滚动容器 _onSizeChanged")
if (this.checkInited(false))
this._onScrolling();
}
//当Item自适应
_onItemAdaptive(item) {
if (this.checkInited(false)) {
let uitf = item.getComponent(UITransform)
if (
(!this._sizeType && uitf.width != this._itemSize.width)
|| (this._sizeType && uitf.height != this._itemSize.height)
) {
if (!this._customSize)
this._customSize = {};
let val = this._sizeType ? uitf.height : uitf.width;
if (this._customSize[item._listId] != val) {
this._customSize[item._listId] = val;
this._resizeContent();
this.updateAll();
// 如果当前正在运行 scrollTo,肯定会不准确,在这里做修正
if (!isNaN(this._scrollToListId)) {
this._scrollPos = null;
this.unschedule(this._scrollToSo);
this.scrollTo(this._scrollToListId, Math.max(0, this._scrollToEndTime - ((new Date()).getTime() / 1000)));
}
}
}
}
}
//Update..
update() {
}
/**
* 创建或更新Item(虚拟列表用)
* @param {Object} data 数据
*/
_createOrUpdateItem(data: any) {
let item: any = this.getItemByListId(data.id);
if (!item) { //如果不存在
let canGet: boolean = this._pool.size() > 0;
if (canGet) {
item = this._pool.get();
} else {
item = instantiate(this._itemTmp);
}
if (item && item._listId != data.id) {
item._listId = data.id;
item.getComponent(UITransform).setContentSize(this._itemSize);
//命名
if (!isNaN(data.id)){
item.name = `svCell_${data.id}`
}
}
item.setPosition(v3(data.x, data.y));
this._resetItemSize(item);
this.content.addChild(item);
if (canGet && this._needUpdateWidget) {
let widget: Widget = item.getComponent(Widget);
if (widget)
widget.updateAlignment();
}
item.setSiblingIndex(this.content.children.length - 1);
let listItem: ScrollviewListItem = item.getComponent(ScrollviewListItem);
item['listItem'] = listItem;
if (listItem) {
listItem.listId = data.id;
listItem.list = this;
listItem._registerEvent();
}
if (this.renderEvent && item) {
EventHandler.emitEvents([this.renderEvent], item, data.id % this._actualNumItems);
}
} else if (this._forceUpdate && this.renderEvent) { //强制更新
item.setPosition(v3(data.x, data.y));
this._resetItemSize(item);
if (this.renderEvent && item) {
EventHandler.emitEvents([this.renderEvent], item, data.id % this._actualNumItems);
}
}
this._resetItemSize(item);
if (this._lastDisplayData.indexOf(data.id) < 0) {
this._lastDisplayData.push(data.id);
}
}
//创建或更新Item(非虚拟列表用)
_createOrUpdateItem2(listId: number) {
let item: any = this.content.children[listId];
let listItem: ScrollviewListItem;
if (!item) { //如果不存在
item = instantiate(this._itemTmp);
item._listId = listId;
this.content.addChild(item);
listItem = item.getComponent(ScrollviewListItem);
item['listItem'] = listItem;
if (listItem) {
listItem.listId = listId;
listItem.list = this;
listItem._registerEvent();
}
if (this.renderEvent && item) {
Component.EventHandler.emitEvents([this.renderEvent], item, listId);
}
} else if (this._forceUpdate && this.renderEvent) { //强制更新
item._listId = listId;
if (listItem)
listItem.listId = listId;
if (this.renderEvent && item) {
Component.EventHandler.emitEvents([this.renderEvent], item, listId);
}
}
if (this._lastDisplayData.indexOf(listId) < 0) {
this._lastDisplayData.push(listId);
}
}
//仅虚拟列表用
_resetItemSize(item: any) {
return;
let size: number;
if (this._customSize && this._customSize[item._listId]) {
size = this._customSize[item._listId];
} else {
if (this._colLineNum > 1)
item.getComponent(UITransform).setContentSize(this._itemSize);
else
size = this._sizeType ? this._itemSize.height : this._itemSize.width;
}
if (size) {
let uitf = item.getComponent(UITransform)
if (this._sizeType)
uitf.height = size;
else
uitf.width = size;
}
}
/**
* 更新Item位置
* @param {Number||Node} listIdOrItem
*/
_updateItemPos(listIdOrItem: any) {
let item: any = isNaN(listIdOrItem) ? listIdOrItem : this.getItemByListId(listIdOrItem);
let pos: any = this.getItemPos(item._listId);
item.setPosition(pos.x, pos.y);
}
/**
* 设置多选
* @param {Array} args 可以是单个listId,也可是个listId数组
* @param {Boolean} bool 值,如果为null的话,则直接用args覆盖
*/
setMultSelected(args: any, bool: boolean) {
if (!this.checkInited())
return;
if (!Array.isArray(args)) {
args = [args];
}
if (bool == null) {
this.multSelected = args;
} else {
let listId: number, sub: number;
if (bool) {
for (let n: number = args.length - 1; n >= 0; n--) {
listId = args[n];
sub = this.multSelected.indexOf(listId);
if (sub < 0) {
this.multSelected.push(listId);
}
}
} else {
for (let n: number = args.length - 1; n >= 0; n--) {
listId = args[n];
sub = this.multSelected.indexOf(listId);
if (sub >= 0) {
this.multSelected.splice(sub, 1);
}
}
}
}
this._forceUpdate = true;
this._onScrolling();
}
/**
* 更新指定的Item
* @param {Array} args 单个listId,或者数组
* @returns
*/
updateItem(args: any) {
if (!this.checkInited())
return;
if (!Array.isArray(args)) {
args = [args];
}
for (let n: number = 0, len: number = args.length; n < len; n++) {
let listId: number = args[n];
let item: any = this.getItemByListId(listId);
if (item)
Component.EventHandler.emitEvents([this.renderEvent], item, listId % this._actualNumItems);
}
}
/**
* 更新全部
*/
updateAll() {
if (!this.checkInited())
return;
this.numItems = this.numItems;
}
/**
* 根据ListID获取Item
* @param {Number} listId
* @returns
*/
getItemByListId(listId: number) {
if (this.content == null) return null;
for (let n: number = this.content.children.length - 1; n >= 0; n--) {
let item: any = this.content.children[n];
if (item._listId == listId)
return item;
}
}
/**
* 获取在显示区域外的Item
* @returns
*/
_getOutsideItem() {
let item: any;
let result: any[] = [];
for (let n: number = this.content.children.length - 1; n >= 0; n--) {
item = this.content.children[n];
let isHas: boolean = false;
for (let idx in this.displayData) {
if (this.displayData[idx].id == item._listId) {
isHas = true;
continue;
}
}
if (!isHas) {
result.push(item);
}
}
return result;
}
//删除显示区域以外的Item
_delRedundantItem() {
if (this._virtual) {
let arr: any[] = this._getOutsideItem();
for (let n: number = arr.length - 1; n >= 0; n--) {
let item: any = arr[n];
if (this._scrollItem && item._listId == this._scrollItem._listId)
continue;
this._pool.put(item);
for (let m: number = this._lastDisplayData.length - 1; m >= 0; m--) {
if (this._lastDisplayData[m] == item._listId) {
this._lastDisplayData.splice(m, 1);
break;
}
}
}
} else {
while (this.content.children.length > this._numItems) {
this._delSingleItem(this.content.children[this.content.children.length - 1]);
}
}
}
//删除单个Item
_delSingleItem(item: any) {
item.removeFromParent();
if (item.destroy)
item.destroy();
item = null;
}
/**
* 动效删除Item(此方法只适用于虚拟列表,即_virtual=true
* 一定要在回调函数里重新设置新的numItems进行刷新,毕竟本List是靠数据驱动的。
*/
aniDelItem(listId: number, callFunc: Function, aniType: number) {
if (!this.checkInited() || !this._virtual)
return //hg_utils.hgLog('This function is not allowed to be called!');
if (this._aniDelRuning)
return //hg_utils.hgLog('Please wait for the current deletion to finish!');
let item: any = this.getItemByListId(listId);
let listItem: ScrollviewListItem;
if (!item) {
callFunc(listId);
return;
} else {
listItem = item.getComponent(ScrollviewListItem);
}
this._aniDelRuning = true;
let curLastId: number = this.displayData[this.displayData.length - 1].id;
let resetSelectedId: boolean = listItem.selected;
listItem.showAni(aniType, () => {
//判断有没有下一个,如果有的话,创建粗来
let newId: number;
if (curLastId < this._numItems - 2) {
newId = curLastId + 1;
}
if (newId != null) {
let newData: any = this._calcItemPos(newId);
this.displayData.push(newData);
if (this._virtual)
this._createOrUpdateItem(newData);
else
this._createOrUpdateItem2(newId);
} else{
this._numItems--;
}
if (this._customSize) {
if (this._customSize[listId])
delete this._customSize[listId];
let newCustomSize: any = {};
let size: number;
for (let id in this._customSize) {
size = this._customSize[id];
let idNumber: number = parseInt(id);
newCustomSize[idNumber - (idNumber >= listId ? 1 : 0)] = size;
}
this._customSize = newCustomSize;
}
//后面的Item向前怼的动效
let sec: number = .2333;
let acts: any[], haveCB: boolean;
for (let n: number = newId != null ? newId : curLastId; n >= listId + 1; n--) {
item = this.getItemByListId(n);
if (item) {
let posData: any = this._calcItemPos(n - 1);
let a_num = 0
let act = tween(item);
act.to(sec, {position: v3(posData.x, posData.y)})
a_num += 1
// acts = [
// cc.moveTo(sec, cc.v2(posData.x, posData.y)),
// ];
if (n <= listId + 1) {
haveCB = true;
act.call(()=>{
this._aniDelRuning = false;
callFunc(listId);
})
a_num += 1
// acts.push(cc.callFunc(() => {
// this._aniDelRuning = false;
// callFunc(listId);
// }));
}
if (a_num > 0)
act.start()
}
}
if (!haveCB) {
this._aniDelRuning = false;
callFunc(listId);
}
}, true);
}
/**
* 滚动到..
* @param {Number} listId 索引(如果<0,则滚到首个Item位置,如果>=_numItems,则滚到最末Item位置)
* @param {Number} timeInSecond 时间
* @param {Number} offset 索引目标位置偏移,0-1
* @param {Boolean} overStress 滚动后是否强调该Item(这只是个实验功能)
*/
scrollTo(listId: number, timeInSecond: number = .5, offset: number = null, overStress: boolean = false) {
if (!this.checkInited(false))
return;
if (timeInSecond == null) //默认0.5
timeInSecond = .5;
else if (timeInSecond < 0)
timeInSecond = 0;
if (listId < 0)
listId = 0;
else if (listId >= this._numItems)
listId = this._numItems - 1;
// 以防设置了numItems之后layout的尺寸还未更新
if (!this._virtual && this._layout && this._layout.enabled)
this._layout.updateLayout();
let pos: any = this.getItemPos(listId);
let targetX: number, targetY: number;
switch (this._alignCalcType) {
case 1://单行HORIZONTALLEFT_TO_RIGHT)、网格VERTICALLEFT_TO_RIGHT
targetX = pos.left;
if (offset != null)
targetX -= this._uitf.width * offset;
else
targetX -= this._leftGap;
pos = v2(targetX, 0);
break;
case 2://单行HORIZONTALRIGHT_TO_LEFT)、网格VERTICALRIGHT_TO_LEFT
targetX = pos.right - this._uitf.width;
if (offset != null)
targetX += this._uitf.width * offset;
else
targetX += this._rightGap;
pos = v2(targetX + this.contentUITF.width, 0);
break;
case 3://单列VERTICALTOP_TO_BOTTOM)、网格HORIZONTALTOP_TO_BOTTOM
targetY = pos.top;
if (offset != null)
targetY += this._uitf.height * offset;
else
targetY += this._topGap;
pos = v2(0, -targetY);
break;
case 4://单列VERTICALBOTTOM_TO_TOP)、网格HORIZONTALBOTTOM_TO_TOP
targetY = pos.bottom + this._uitf.height;
if (offset != null)
targetY -= this._uitf.height * offset;
else
targetY -= this._bottomGap;
pos = v2(0, -targetY + this.contentUITF.height);
break;
}
let viewPos: any = this.content.getPosition();
viewPos = Math.abs(this._sizeType ? viewPos.y : viewPos.x);
let comparePos = this._sizeType ? pos.y : pos.x;
let runScroll = Math.abs((this._scrollPos != null ? this._scrollPos : viewPos) - comparePos) > .5;
if (runScroll) {
this._scrollView.scrollToOffset(pos, timeInSecond);
this._scrollToListId = listId;
this._scrollToEndTime = ((new Date()).getTime() / 1000) + timeInSecond;
this._scrollToSo = this.scheduleOnce(() => {
if (!this._adheringBarrier) {
this.adhering = this._adheringBarrier = false;
}
this._scrollPos =
this._scrollToListId =
this._scrollToEndTime =
this._scrollToSo =
null;
if (overStress) {
let item = this.getItemByListId(listId);
if (item) {
tween(item)
.to(0.1, {scale: v3(1.05, 1.05, 1.05)})
.to(0.1, {scale: v3(1, 1, 1)})
.start()
}
}
}, timeInSecond + .1);
if (timeInSecond <= 0) {
this._onScrolling();
}
}
}
/**
* 计算当前滚动窗最近的Item
*/
_calcNearestItem() {
this.nearestListId = null;
let data: any, center: number;
if (this._virtual)
this._calcViewPos();
let vTop: number, vRight: number, vBottom: number, vLeft: number;
vTop = this.viewTop;
vRight = this.viewRight;
vBottom = this.viewBottom;
vLeft = this.viewLeft;
let breakFor: boolean = false;
for (let n = 0; n < this.content.children.length && !breakFor; n += this._colLineNum) {
data = this._virtual ? this.displayData[n] : this._calcExistItemPos(n);
if (!data)
break;
center = this._sizeType ? ((data.top + data.bottom) / 2) : (center = (data.left + data.right) / 2);
switch (this._alignCalcType) {
case 1://单行HORIZONTALLEFT_TO_RIGHT)、网格VERTICALLEFT_TO_RIGHT
if (data.right >= vLeft) {
this.nearestListId = data.id;
if (vLeft > center)
this.nearestListId += this._colLineNum;
breakFor = true;
}
break;
case 2://单行HORIZONTALRIGHT_TO_LEFT)、网格VERTICALRIGHT_TO_LEFT
if (data.left <= vRight) {
this.nearestListId = data.id;
if (vRight < center)
this.nearestListId += this._colLineNum;
breakFor = true;
}
break;
case 3://单列VERTICALTOP_TO_BOTTOM)、网格HORIZONTALTOP_TO_BOTTOM
if (data.bottom <= vTop) {
this.nearestListId = data.id;
if (vTop < center)
this.nearestListId += this._colLineNum;
breakFor = true;
}
break;
case 4://单列VERTICALBOTTOM_TO_TOP)、网格HORIZONTALBOTTOM_TO_TOP
if (data.top >= vBottom) {
this.nearestListId = data.id;
if (vBottom > center)
this.nearestListId += this._colLineNum;
breakFor = true;
}
break;
}
}
//判断最后一个Item。。。(哎,这些判断真心恶心,判断了前面的还要判断最后一个。。。一开始呢,就只有一个布局(单列布局),那时候代码才三百行,后来就想着完善啊,艹..这坑真深,现在这行数都一千五了= =||)
data = this._virtual ? this.displayData[this.displayItemNum - 1] : this._calcExistItemPos(this._numItems - 1);
if (data && data.id == this._numItems - 1) {
center = this._sizeType ? ((data.top + data.bottom) / 2) : (center = (data.left + data.right) / 2);
switch (this._alignCalcType) {
case 1://单行HORIZONTALLEFT_TO_RIGHT)、网格VERTICALLEFT_TO_RIGHT
if (vRight > center)
this.nearestListId = data.id;
break;
case 2://单行HORIZONTALRIGHT_TO_LEFT)、网格VERTICALRIGHT_TO_LEFT
if (vLeft < center)
this.nearestListId = data.id;
break;
case 3://单列VERTICALTOP_TO_BOTTOM)、网格HORIZONTALTOP_TO_BOTTOM
if (vBottom < center)
this.nearestListId = data.id;
break;
case 4://单列VERTICALBOTTOM_TO_TOP)、网格HORIZONTALBOTTOM_TO_TOP
if (vTop > center)
this.nearestListId = data.id;
break;
}
}
}
//计算 CustomSize(这个函数还是保留吧,某些罕见的情况的确还是需要手动计算customSize的)
calcCustomSize(numItems: number) {
if (!this.checkInited())
return;
if (!this._itemTmp)
return //hg_utils.hgLog('Unset template item!');
if (!this.renderEvent)
return //hg_utils.hgLog('Unset Render-Event!');
this._customSize = {};
let temp: any = instantiate(this._itemTmp);
this.content.addChild(temp);
let uitf = temp.getComponent(UITransform)
for (let n: number = 0; n < numItems; n++) {
Component.EventHandler.emitEvents([this.renderEvent], temp, n);
if (uitf.height != this._itemSize.height || uitf.width != this._itemSize.width) {
this._customSize[n] = this._sizeType ? uitf.height : uitf.width;
}
}
if (!Object.keys(this._customSize).length)
this._customSize = null;
temp.removeFromParent();
if (temp.destroy)
temp.destroy();
return this._customSize;
}
}