/* * @Author: steveJobs * @Email: icipiqkm@gmail.com * @Date: 2021-8-1 01:15:04 * @Last Modified by: steveJobs * @Last Modified time: 2021-8-1 14:35:43 * @Description: */ import UISuperScrollview from "./UISuperScrollView"; const { ccclass, property } = cc._decorator; const EPSILON = 1e-4; enum Type { HORIZONTAL = 0, VERTICAL = 1, } cc.Enum(Type); enum VerticalAxisDirection { TOP_TO_BOTTOM = 0, BOTTOM_TO_TOP = 1 } cc.Enum(VerticalAxisDirection); enum HorizontalAxisDirection { LEFT_TO_RIGHT = 0, RIGHT_TO_LEFT = 1 } cc.Enum(HorizontalAxisDirection); enum ScrollDirection { NONE = 0, HEADER = 1, FOOTER = 2, } enum IndexVerticalAxisDirection { TOP = 0, BOTTOM = 1, } cc.Enum(IndexVerticalAxisDirection); enum IndexHorizontalAxisDirection { LEFT = 0, RIGHT = 1 } cc.Enum(IndexHorizontalAxisDirection); @ccclass export default class UISuperLayout extends cc.Component { static VerticalAxisDirection = VerticalAxisDirection; static HorizontalAxisDirection = HorizontalAxisDirection; @property(UISuperScrollview) scrollView: UISuperScrollview = null; @property(cc.Node) view: cc.Node = null; @property(cc.Prefab) prefab: cc.Prefab = null; @property({ type: Type }) layoutType: Type = Type.VERTICAL; @property({ type: IndexVerticalAxisDirection, visible: function () { return (this as any).layoutType == Type.VERTICAL && !(this as any).autoCenter; } }) indexVerticalAxisDirection = IndexVerticalAxisDirection.TOP; @property({ type: IndexHorizontalAxisDirection, visible: function () { return (this as any).layoutType == Type.HORIZONTAL && !(this as any).autoCenter; } }) indexHorizontalAxisDirection = IndexHorizontalAxisDirection.LEFT; @property({ type: VerticalAxisDirection }) verticalAxisDirection = VerticalAxisDirection.TOP_TO_BOTTOM; @property({ type: HorizontalAxisDirection }) horizontalAxisDirection = HorizontalAxisDirection.LEFT_TO_RIGHT; @property({ tooltip: "最小值=1,大于1就是Grid模式" }) groupItemTotal: number = 1; @property({ tooltip: "决定最多创建Prefab的数量" }) multiple: number = 2; @property({ tooltip: "顶部填充" }) paddingTop: number = 0; @property({ tooltip: "底部填充" }) paddingBottom: number = 0; @property({ tooltip: "左侧填充" }) paddingLeft: number = 0; @property({ tooltip: "右侧填充" }) paddingRight: number = 0; @property({ tooltip: "横轴间距" }) spacingX: number = 0; @property({ tooltip: "纵轴间距" }) spacingY: number = 0; @property({ tooltip: "计算缩放后的尺寸" }) affectedByScale: boolean = false; @property({ tooltip: "开启翻页模式" }) isPageView: boolean = false; @property({ tooltip: "每个页面翻页时所需时间。单位:秒", visible: function () { return (this as any).isPageView; } }) pageTurningSpeed = 0.3; @property({ type: cc.PageViewIndicator, visible: function () { return (this as any).isPageView; } }) indicator: cc.PageViewIndicator = null; @property({ slide: true, range: [0, 1, 0.01], tooltip: "滚动临界值,默认单位百分比,当拖拽超出该数值时,松开会自动滚动下一页,小于时则还原", visible: function () { return (this as any).isPageView; } }) scrollThreshold = 0.5; @property({ tooltip: "快速滑动翻页临界值。当用户快速滑动时,会根据滑动开始和结束的距离与时间计算出一个速度值,该值与此临界值相比较,如果大于临界值,则进行自动翻页", visible: function () { return (this as any).isPageView; } }) autoPageTurningThreshold = 100; @property({ type: cc.Component.EventHandler, visible: function () { return (this as any).isPageView; } }) pageEvents: cc.Component.EventHandler[] = []; @property({ tooltip: "开启自动居中", visible: function () { return !(this as any).isPageView; } }) autoCenter: boolean = false; @property({ tooltip: "自动居中的滚动时间", visible: function () { return (this as any).autoCenter; } }) centerTime: number = 1; @property({ type: cc.Node, tooltip: "自动居中的参考节点,如果为空、则默认选择View中心", visible: function () { return (this as any).autoCenter; } }) centerNode: cc.Node = null; @property({ tooltip: "自动居中时、Item的居中锚点", // visible: function () { return (this as any).autoCenter; } }) centerAnchor: cc.Vec2 = new cc.Vec2(.5, .5); @property({ tooltip: "上/左 无限循环" }) headerLoop: boolean = false; @property({ tooltip: "下/右 无限循环" }) footerLoop: boolean = false; @property(cc.Component.EventHandler) refreshItemEvents: cc.Component.EventHandler[] = []; private stretchLock: { index?: number, timeInSecond?: number, boundary?: cc.Vec2, reverse?: boolean, } = {}; private _currPageIndex: number = 0; get currPageIndex() { return this._currPageIndex; } private _lastPageIndex: number = 0; get lastPageIndex() { return this._lastPageIndex; } private isRestart: boolean = false; /** 当前滚动方向 */ private scrollDirection: ScrollDirection = ScrollDirection.NONE; /** 是否垂直滚动 */ get vertical(): boolean { return this.layoutType == Type.VERTICAL; } /** 是否水平滚动 */ get horizontal(): boolean { return this.layoutType == Type.HORIZONTAL; } get transform(): cc.Node { return this.node; } /** View 可容纳的宽度 */ get accommodWidth() { return this.view.width - this.paddingLeft - this.paddingRight; } /** View 可容纳的高度 */ get accommodHeight() { return this.view.height - this.paddingTop - this.paddingBottom; } /** 头部的节点 */ get header(): cc.Node { if (this.node.children.length == 0) return null; return this.node.children[0]; } /** 底部的节点 */ get footer(): cc.Node { if (this.node.children.length == 0) return null; return this.node.children[this.node.children.length - 1]; } /** 头部索引 */ get headerIndex(): number { if (!this.header) return -1; let node: any = this.header; return node["__index"]; } /** 底部索引 */ get footerIndex(): number { if (!this.footer) return -1; let node: any = this.footer; return node["__index"]; } /** Item起始位置 */ get viewStartPoint(): cc.Vec3 { let pos = new cc.Vec3(); if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { pos.x = this.view.width * -0.5 + this.paddingLeft; } else { pos.x = this.view.width * 0.5 - this.paddingRight; } if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { pos.y = this.view.height * 0.5 - this.paddingTop; } else { pos.y = this.view.height * -0.5 + this.paddingBottom; } return pos; } /** View 头部边界 */ get viewHeaderBoundary(): number { return this.vertical ? this.view.height * 0.5 : this.view.width * -0.5; } /** View 底部边界 */ get viewFooterBoundary(): number { return this.vertical ? this.view.height * -0.5 : this.view.width * 0.5; } /** 头部节点边界 */ get headerBoundary(): number { if (!this.header) return 0; if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { return this.node.position.y + this.getItemYMax(this.header) + this.paddingTop; } else { return this.node.position.y + this.getItemYMin(this.header) - this.paddingBottom; } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { return this.node.position.x + this.getItemXMin(this.header) - this.paddingLeft; } else { return this.node.position.x + this.getItemXMax(this.header) + this.paddingRight; } } } /** 底部节点边界 */ get footerBoundary(): number { if (!this.footer) return 0; if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { return this.node.position.y + this.getItemYMin(this.footer) - this.paddingBottom; } else { return this.node.position.y + this.getItemYMax(this.footer) + this.paddingTop; } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { return this.node.position.x + this.getItemXMax(this.footer) + this.paddingRight; } else { return this.node.position.x + this.getItemXMin(this.footer) - this.paddingLeft; } } } /** 自动居中节点头部边界 */ get centerHeaderBoundary() { let key = this.vertical ? "y" : "x"; var offset; if (this.centerNode) { offset = this.viewHeaderBoundary - (this.centerNode.position as any)[key]; } else { offset = this.viewHeaderBoundary - (this.view.position as any)[key]; } if (this.vertical && this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM || this.horizontal && this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { return this.headerBoundary + offset; } else { return this.footerBoundary + offset; } } /** 自动居中节点底部边界 */ get centerFooterBoundary() { let key = this.vertical ? "y" : "x"; var offset; if (this.centerNode) { offset = this.viewFooterBoundary - (this.centerNode.position as any)[key]; } else { offset = this.viewFooterBoundary - (this.view.position as any)[key]; } if (this.vertical && this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM || this.horizontal && this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { return this.footerBoundary + offset; } else { return this.headerBoundary + offset; } } /** 是否超出左侧边界 */ get isOfLeftBoundary(): number { if (this.vertical) return 0; if (this.autoCenter) { if (this.scrollDirection == ScrollDirection.HEADER) { return this.centerHeaderBoundary; } return 0; } if (this.headerLoop) { if (this.header) return 0; return this.viewHeaderBoundary + this.node.position.x; } if (!this.header || this.fixedItemWidth <= this.view.width) { return this.viewHeaderBoundary + this.node.position.x; } if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (this.headerIndex == 0) { return this.headerBoundary; } } else { if (this.footerIndex == this.itemTotal - 1) { return this.footerBoundary; } } return 0; } /** 是否超出顶部边界 */ get isOfTopBoundary(): number { if (!this.vertical) return 0; if (this.autoCenter) { if (this.scrollDirection == ScrollDirection.HEADER) { return this.centerHeaderBoundary; } return 0; } if (this.headerLoop) { if (this.header) return 0; return this.viewHeaderBoundary + this.node.position.y; } if (!this.header || this.fixedItemHeight <= this.view.height) { return this.viewHeaderBoundary + this.node.position.y; } if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (this.headerIndex == 0) { return this.headerBoundary; } } else { if (this.footerIndex == this.itemTotal - 1) { return this.footerBoundary; } } return 0; } /** 是否超出右侧边界 */ get isOfRightBoundary(): number { if (this.vertical) return 0; if (this.autoCenter) { if (this.scrollDirection == ScrollDirection.FOOTER) { return this.centerFooterBoundary; } return 0; } if (this.footerLoop) { if (this.footer) return 0; return this.viewFooterBoundary + this.node.position.x; } if (!this.footer || this.fixedItemWidth <= this.view.width) { return this.viewFooterBoundary + this.node.position.x; } if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (this.footerIndex == this.itemTotal - 1) { return this.footerBoundary; } } else { if (this.headerIndex == 0) { return this.headerBoundary; } } return 0; } /** 是否超出底部边界 */ get isOfButtomBoundary(): number { if (!this.vertical) return 0; if (this.autoCenter) { if (this.scrollDirection == ScrollDirection.FOOTER) { return this.centerFooterBoundary; } return 0; } if (this.footerLoop) { if (this.footer) return 0; return this.viewFooterBoundary + this.node.position.y; } if (!this.footer || this.fixedItemHeight <= this.view.height) { return this.viewFooterBoundary + this.node.position.y; } if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (this.footerIndex == this.itemTotal - 1) { return this.footerBoundary; } } else { if (this.headerIndex == 0) { return this.headerBoundary; } } return 0; } /** 从头部到底部的所有Item高度总和 */ get fixedItemHeight(): number { if (!this.header) return 0; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { return Math.abs(this.getItemYMax(this.header)) + Math.abs(this.getItemYMin(this.footer)); } else { return Math.abs(this.getItemYMin(this.header)) + Math.abs(this.getItemYMax(this.footer)); } } /** 从头部到底部的所有Item宽度总和 */ get fixedItemWidth(): number { if (!this.header) return 0; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { return Math.abs(this.getItemXMin(this.header)) + Math.abs(this.getItemXMax(this.footer)); } else { return Math.abs(this.getItemXMax(this.header)) + Math.abs(this.getItemXMin(this.footer)); } } /** 返回 header到 footer 之间的整体尺寸 如果Item数量不足以撑开View 则返回View尺寸 最小值是View尺寸 */ get contentSize(): cc.Size { if (this.node.children.length == 0) return this.view.getContentSize(); let size = new cc.Size(this.view.getContentSize().width, this.view.getContentSize().height); if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { size.height = this.headerBoundary + -this.footerBoundary; } else { size.height = this.footerBoundary + -this.headerBoundary; } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { size.width = this.footerBoundary + -this.headerBoundary; } else { size.width = this.headerBoundary + -this.footerBoundary; } } if (size.width < this.view.getContentSize().width) { size.width = this.view.getContentSize().width; } if (size.height < this.view.getContentSize().height) { size.height = this.view.getContentSize().height; } return size; } private prevPos: cc.Vec3 = new cc.Vec3(0, 0, 0); private _maxPrefabTotal: number = 0; /** 已被创建的Item数量 */ get maxPrefabTotal(): number { return this._maxPrefabTotal; } private currentCreateItemTotal: number = 0; private _itemTotal: number = 0; /** 数据长度 */ get itemTotal(): number { return this._itemTotal; } private _centerPosition: cc.Vec3; /** 自动居中的参考位置 */ get centerPosition(): cc.Vec3 { if (!this._centerPosition) { this._centerPosition = new cc.Vec3(); if (this.autoCenter) { if (this.centerNode) { let worldPos = this.centerNode.parent.convertToWorldSpaceAR(this.centerNode.position); this._centerPosition = this.view.convertToNodeSpaceAR(worldPos); } } else { if (this.vertical) { if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { this._centerPosition.y = this.viewHeaderBoundary; } else { this._centerPosition.y = this.viewFooterBoundary; } } else { if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { this._centerPosition.x = this.viewHeaderBoundary; } else { this._centerPosition.x = this.viewFooterBoundary; } } } } return this._centerPosition; } onLoad() { this.transform.setAnchorPoint(new cc.Vec2(.5, .5)); this.transform.setContentSize(this.view.getContentSize()); this.node.setPosition(cc.Vec3.ZERO); if (this.isPageView) this.autoCenter = false; this.scrollView.view.on(cc.Node.EventType.SIZE_CHANGED, this.onViewSizeChange, this); Object.defineProperty(this.transform, "getContentSize", { get: () => () => this.contentSize }); Object.defineProperty(this.transform, "contentSize", { get: () => this.contentSize }); Object.defineProperty(this.transform, "width", { get: () => this.contentSize.width }); Object.defineProperty(this.transform, "height", { get: () => this.contentSize.height }); } onEnable() { this.addEventListener(); } onDisable() { this.removeEventListener(); } /** * 更新item数量 * @param count * @param onRefreshLastItem 如果你确定只需要刷新最后一个item 那么这个设置成true 就不会刷新所有数据 */ public CreateItem(count: number, refreshLastItem: boolean = false): this { this.currentCreateItemTotal = count; this.scrollDirection = ScrollDirection.HEADER; this.createItems(count, refreshLastItem); let offset = count - this.itemTotal; this._itemTotal = count; this.refreshItems(offset, refreshLastItem); if (!refreshLastItem) this.updateItems(); this.scrollView.startAutoScroll(); this.scrollView.release(); if (this.indicator) { this.indicator.setPageView((this.scrollView as any)); } if (this.autoCenter) { this.scrollToCenter(); } return this; } /** * 刷新所有item */ updateItems(): this { this.resetIndexStartToEnd(this.headerIndex); return this; } /** 告知组件你的节点尺寸 */ updateItemSize(node: cc.Node, size: cc.Size) { if (this.groupItemTotal > 1) return; if (!node || !size) return; // 20220209 開啟會導致對應位置的組件被重置錯誤Size by豆豆 // (node as any)["__runtime_size"] = size; this.onChangeChildSize(node); } /** 自动居中到最近Item */ scrollToCenter() { this.soonFinish(); } /** 滚动到头部 */ scrollToHeader(timeInSecond?: number) { var headerOrFooter = 0; if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { headerOrFooter = this.viewHeaderBoundary; if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.BOTTOM) { headerOrFooter -= this.header.height + this.paddingTop + this.paddingBottom; } } else { headerOrFooter = this.viewFooterBoundary; if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { headerOrFooter += this.header.height + this.paddingTop + this.paddingBottom; } } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { headerOrFooter = this.viewHeaderBoundary; if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.RIGHT) { headerOrFooter += this.header.width + this.paddingLeft + this.paddingRight; } } else { headerOrFooter = this.viewFooterBoundary; if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { headerOrFooter -= this.header.width + this.paddingLeft + this.paddingRight; } } } this.scrollToIndex(0, timeInSecond, new cc.Vec2(headerOrFooter, headerOrFooter)); } /** 滚动到尾部 */ scrollToFooter(timeInSecond?: number) { var headerOrFooter = 0; if (this.vertical) { if (this.fixedItemHeight < this.view.height) return; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { headerOrFooter = this.viewFooterBoundary; if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.BOTTOM) { headerOrFooter += this.footer.height + this.paddingTop + this.paddingBottom; } } else { headerOrFooter = this.viewHeaderBoundary; if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { headerOrFooter -= this.footer.height + this.paddingTop + this.paddingBottom; } } } else { if (this.fixedItemWidth < this.view.width) return; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { headerOrFooter = this.viewFooterBoundary; if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.RIGHT) { headerOrFooter -= this.footer.width + this.paddingLeft + this.paddingRight; } } else { headerOrFooter = this.viewHeaderBoundary; if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { headerOrFooter += this.footer.width + this.paddingLeft + this.paddingRight; } } } this.scrollToIndex(this.itemTotal - 1, timeInSecond, new cc.Vec2(headerOrFooter, headerOrFooter), true); } private isNearFooter(index: number) { let nearFooter = false; let flag = index > this.footerIndex && index < this.headerIndex; if (flag) { let result = Math.abs(index - this.headerIndex) < Math.abs(index - this.footerIndex); if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { nearFooter = !result; } else { nearFooter = result; } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { nearFooter = !result; } else { nearFooter = result; } } } else if (index > this.footerIndex) { if (this.vertical) { nearFooter = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? true : false; } else { nearFooter = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? true : false; } } else if (index < this.headerIndex) { if (this.vertical) { nearFooter = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? false : true; } else { nearFooter = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? false : true; } } return nearFooter; } private getFooterOffset(index: number) { let footerOffset = this.footerIndex % this.groupItemTotal; let indexOffset = index % this.groupItemTotal; return indexOffset - footerOffset + this.groupItemTotal; } private getHeaderOffset(index: number) { let headerOffset = this.headerIndex % this.groupItemTotal; let indexOffset = index % this.groupItemTotal; return headerOffset - indexOffset + this.groupItemTotal; } private offsetToHeader(index: number) { var offset = 0; if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { offset = this.getHeaderOffset(index); } else { offset = this.getFooterOffset(index); } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { offset = this.getHeaderOffset(index); } else { offset = this.getFooterOffset(index); } } offset -= this.groupItemTotal; for (let i = 0; i < offset; i++) { this.pushToHeader(true); } } private offsetToFooter(index: number) { var offset = 0; if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { offset = this.getFooterOffset(index); } else { offset = this.getHeaderOffset(index); } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { offset = this.getFooterOffset(index); } else { offset = this.getHeaderOffset(index); } } offset -= this.groupItemTotal; for (let i = 0; i < offset; i++) { this.pushToFooter(true); } } private resetIndexStartToEnd(index: number) { for (let i = 0; i < this.node.children.length; i++) { const child: any = this.node.children[i]; child["__index"] = index; index++; if (this.headerLoop || this.footerLoop) { if (index < 0 || index >= this.itemTotal) { index = 0; } } this.notifyRefreshItem(child); } } private resetIndexEndToStart(index: number) { for (let i = this.node.children.length - 1; i >= 0; i--) { const child: any = this.node.children[i]; child["__index"] = index; index--; if (this.headerLoop || this.footerLoop) { if (index < 0) { index = this.itemTotal - 1; } } this.notifyRefreshItem(child); } } /** 跳转到指定索引位置 */ scrollToIndex(index: number, timeInSecond?: number, boundary?: cc.Vec2, reverse: boolean = false) { if (isNaN(index) || index < 0 || index > this.itemTotal - 1) return; this.scrollView.stopAutoScroll(); if (this.isPageView) { this.scrollView.savePageIndex(index); } var child = this.node.children.find((item: any) => item["__index"] == index); var nearFooter = this.isNearFooter(index); this.stretchLock.index = index; this.stretchLock.timeInSecond = timeInSecond; this.stretchLock.boundary = boundary; this.stretchLock.reverse = reverse; if (!child) { if (index == 0) { this.pushToHeader(); } if (index == this.itemTotal - 1) { this.pushToFooter(); } var flag = this.vertical && this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM || !this.vertical && this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT; if (nearFooter) { this.offsetToFooter(index); flag ? this.resetIndexEndToStart(index) : this.resetIndexStartToEnd(index); } else { this.offsetToHeader(index); flag ? this.resetIndexStartToEnd(index) : this.resetIndexEndToStart(index); } child = this.node.children.find((item: any) => item["__index"] == index); } if (!child) return; let itemPos = child.getPosition().clone(); if (!this.autoCenter) { if (this.vertical) { if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { if (!reverse) { itemPos.y = this.getItemYMax(child) + this.paddingTop; } else { itemPos.y = this.getItemYMin(child) - this.paddingBottom; } } else { if (!reverse) { itemPos.y = this.getItemYMin(child) - this.paddingBottom; } else { itemPos.y = this.getItemYMax(child) + this.paddingTop; } } } else { if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { if (!reverse) { itemPos.x = this.getItemXMin(child) - this.paddingLeft; } else { itemPos.x = this.getItemXMax(child) + this.paddingRight; } } else { if (!reverse) { itemPos.x = this.getItemXMax(child) + this.paddingRight; } else { itemPos.x = this.getItemXMin(child) - this.paddingLeft; } } } } let worldPos = this.transform.convertToWorldSpaceAR(itemPos); let localPos = this.view.convertToNodeSpaceAR(worldPos); var multiple; if (!this.autoCenter && boundary) { multiple = boundary; } else { multiple = this.getCenterAnchor(child, this.centerPosition); } localPos.x *= -1; localPos.y *= -1; localPos = localPos.add(multiple); this.scrollView.scrollToAny(localPos, timeInSecond, true); } protected async onViewSizeChange() { this.isRestart = true; this.createItems(this.currentCreateItemTotal); this.resetChilds(true); this.scrollToHeader(); for (let i = 0; i < this.node.children.length; i++) { const child: any = this.node.children[i]; const transform = child; this.setAndSaveSizeAndScale(transform); } this.isRestart = false; } protected setAndSaveSizeAndScale(item: cc.Node) { item.setContentSize(this.getItemSize(item)); item["__size"] = item.getContentSize().clone(); item["__scale"] = cc.v2(item.scaleX, item.scaleY); } /** 根据centerAnchor计算自动居中的真实位置 */ protected getCenterAnchor(item: cc.Node, center: cc.Vec3) { var pos = center.clone(); if (this.vertical) { let anchor = item.height * this.centerAnchor.y; let origin = item.height * item.anchorY; pos.y -= anchor - origin; } else { let anchor = item.width * this.centerAnchor.x; let origin = item.width * item.anchorX; pos.x += anchor - origin; } return pos; } /** 滚动即将结束时 跑自动居中的逻辑 */ protected soonFinish() { if (!this.autoCenter) return; if (this.scrollView.pullRefresh) return; this.scrollView.stopAutoScroll(); var findedPos = new cc.Vec2(999999, 999999); for (let i = 0; i < this.node.children.length; i++) { const child = this.node.children[i]; let worldPos = this.transform.convertToWorldSpaceAR(child.position)!; let localPos = this.view.convertToNodeSpaceAR(worldPos); let map = { width: false, height: false }; var multiple = this.getCenterAnchor(child, this.centerPosition); localPos.x -= multiple.x; localPos.y -= multiple.y; let newLocalPos = localPos; map.width = Math.abs(newLocalPos.x) < Math.abs(findedPos.x); map.height = Math.abs(newLocalPos.y) < Math.abs(findedPos.y); if (this.vertical && map.height) { findedPos = cc.v2(newLocalPos.x, newLocalPos.y); } else if (!this.vertical && map.width) { findedPos = cc.v2(newLocalPos.x, newLocalPos.y); } } findedPos.x *= -1; findedPos.y *= -1; this.scrollView.scrollToAny(findedPos, this.centerTime); } /** 根据groupItemTotal和View可容纳的尺寸 来平均分配Item该有的尺寸 */ protected getItemSize(item: cc.Node): cc.Size { let size = new cc.Size(0, 0); if (this.vertical) { let spacing = this.spacingX * (this.groupItemTotal - 1); size.width = (this.accommodWidth - spacing) / this.groupItemTotal; size.height = item.height; } else { let spacing = this.spacingY * (this.groupItemTotal - 1); size.height = (this.accommodHeight - spacing) / this.groupItemTotal; size.width = item.width; } return size; } /** 获取Item的YMax */ protected getItemYMax(item: cc.Node | null): number { if (!item) return 0; let height = this.getScaleHeight(item) * (1 - item.anchorY); return item.position.y + height; } /** 获取Item的YMin */ protected getItemYMin(item: cc.Node | null): number { if (!item) return 0; let height = this.getScaleHeight(item) * item.anchorY; return item.position.y - height; } /** 获取Item的XMax */ protected getItemXMax(item: cc.Node | null): number { if (!item) return 0; let width = this.getScaleWidth(item) * (1 - item.anchorX); return item.position.x + width; } /** 获取Item的XMin */ protected getItemXMin(item: cc.Node | null): number { if (!item) return 0; let width = this.getScaleWidth(item) * item.anchorX; return item.position.x - width; } /** 获取一组Item中起始位置X */ protected getStartX(item: cc.Node | null): number { if (!item) return 0; var x = 0; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { let width = this.getScaleWidth(item) * item.anchorX; x = this.viewStartPoint.x + width; } else { let width = this.getScaleWidth(item) * (1 - item.anchorX); x = this.viewStartPoint.x - width; } return x; } /** 获取一组Item中结束位置X */ protected getEndX(item: cc.Node | null): number { if (!item) return 0; var x = 0; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { let width = this.getScaleWidth(item) * (1 - item.anchorX); x = -this.viewStartPoint.x - width - this.paddingRight + this.paddingLeft; } else { let width = this.getScaleWidth(item) * item.anchorX; x = -this.viewStartPoint.x + width + this.paddingLeft - this.paddingRight; } return x; } /** 获取一组Item中起始位置Y */ protected getStartY(item: cc.Node | null): number { if (!item) return 0; var y = 0; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { let height = this.getScaleHeight(item) * (1 - item.anchorY); y = this.viewStartPoint.y - height; } else { let height = this.getScaleHeight(item) * item.anchorY; y = this.viewStartPoint.y + height; } return y; } /** 获取一组Item中结束位置Y */ protected getEndY(item: cc.Node | null): number { if (!item) return 0; var y = 0; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { let height = this.getScaleHeight(item) * item.anchorY; y = -this.viewStartPoint.y + height + this.paddingBottom - this.paddingTop; } else { let height = this.getScaleHeight(item) * (1 - item.anchorY); y = -this.viewStartPoint.y - height - this.paddingTop + this.paddingBottom; } return y; } /** relative的顶部是否有也容纳空间 */ protected isAccommodateByTop(relative: cc.Node) { var max = this.getItemYMax(relative); return max + this.paddingTop < this.accommodHeight * 0.5; } /** relative的底部是否有也容纳空间 */ protected isAccommodateByBottom(relative: cc.Node) { var min = this.getItemYMin(relative); return min - this.paddingBottom > this.accommodHeight * -0.5; } /** relative的左侧是否有也容纳空间 */ protected isAccommodateByLeft(relative: cc.Node) { var min = this.getItemXMin(relative); return min - this.paddingLeft > this.accommodWidth * -0.5; } /** relative的右侧是否有也容纳空间 */ protected isAccommodateByRight(relative: cc.Node) { var max = this.getItemXMax(relative); return max + this.paddingRight < this.accommodWidth * 0.5; } /** relative的左侧位置 */ protected getRelativeByLeft(item: cc.Node, relative: cc.Node): number { var min = this.getItemXMin(relative); return min - this.spacingX - this.getScaleWidth(item) * (1 - item.anchorX); } /** relative的右侧位置 */ protected getRelativeByRight(item: cc.Node, relative: cc.Node): number { var max = this.getItemXMax(relative); return max + this.spacingX + this.getScaleWidth(item) * item.anchorX; } /** relative的顶部位置 */ protected getRelativeByTop(item: cc.Node, relative: cc.Node): number { var max = this.getItemYMax(relative); return max + this.spacingY + this.getScaleHeight(item) * item.anchorY; } /** relative的底部位置 */ protected getRelativeByBottom(item: cc.Node, relative: cc.Node): number { var min = this.getItemYMin(relative); return min - this.spacingY - this.getScaleHeight(item) * (1 - item.anchorY); } /** 设置Item的坐标位置 */ protected setItemPosition(item: cc.Node, relative: cc.Node, reverse: boolean = false, isHeader: boolean = false) { var pos = new cc.Vec3(); if (isHeader) { pos.x = this.getStartX(item); pos.y = this.getStartY(item); } else { if (this.vertical) { pos = this.getVerticalRelativePosition(item, relative, reverse); } else { pos = this.getHorizontalRelativePosition(item, relative, reverse); } } item.setPosition(pos); } /** 计算垂直模式的Item应该的位置 */ protected getVerticalRelativePosition(item: cc.Node, relative: cc.Node, reverse: boolean) { var pos = new cc.Vec3(); var isAccommodate = false; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { isAccommodate = !reverse ? this.isAccommodateByRight(relative) : this.isAccommodateByLeft(relative); } else { isAccommodate = !reverse ? this.isAccommodateByLeft(relative) : this.isAccommodateByRight(relative); } // 横轴 if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (!reverse) { pos.x = isAccommodate ? this.getRelativeByRight(item, relative) : this.getStartX(item); } else { pos.x = isAccommodate ? this.getRelativeByLeft(item, relative) : this.getEndX(item); } } else { if (!reverse) { pos.x = isAccommodate ? this.getRelativeByLeft(item, relative) : this.getStartX(item); } else { pos.x = isAccommodate ? this.getRelativeByRight(item, relative) : this.getEndX(item); } } // 纵轴 if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (!reverse) { pos.y = isAccommodate ? relative.position.y : this.getRelativeByBottom(item, relative); } else { pos.y = isAccommodate ? relative.position.y : this.getRelativeByTop(item, relative); } } else { if (!reverse) { pos.y = isAccommodate ? relative.position.y : this.getRelativeByTop(item, relative); } else { pos.y = isAccommodate ? relative.position.y : this.getRelativeByBottom(item, relative); } } return pos; } /** 计算水平模式的Item应该的位置 */ protected getHorizontalRelativePosition(item: cc.Node, relative: cc.Node, reverse: boolean) { var pos = new cc.Vec3(); var isAccommodate = false; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { isAccommodate = !reverse ? this.isAccommodateByBottom(relative) : this.isAccommodateByTop(relative); } else { isAccommodate = !reverse ? this.isAccommodateByTop(relative) : this.isAccommodateByBottom(relative); } // 纵轴 if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (!reverse) { pos.y = isAccommodate ? this.getRelativeByBottom(item, relative) : this.getStartY(item); } else { pos.y = isAccommodate ? this.getRelativeByTop(item, relative) : this.getEndY(item); } } else { if (!reverse) { pos.y = isAccommodate ? this.getRelativeByTop(item, relative) : this.getStartY(item); } else { pos.y = isAccommodate ? this.getRelativeByBottom(item, relative) : this.getEndY(item); } } // 横轴 if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (!reverse) { pos.x = isAccommodate ? relative.position.x : this.getRelativeByRight(item, relative); } else { pos.x = isAccommodate ? relative.position.x : this.getRelativeByLeft(item, relative); } } else { if (!reverse) { pos.x = isAccommodate ? relative.position.x : this.getRelativeByLeft(item, relative); } else { pos.x = isAccommodate ? relative.position.x : this.getRelativeByRight(item, relative); } } return pos; } /** 当数据长度发生变化时 计算item应该怎么排列 */ protected refreshItems(offset: number, refreshLastItem: boolean = false) { if (offset < 0) { var prev = this.header; if (this.contentSize.height == this.view.height) { for (let i = 0; i < this.node.children.length; i++) { const child = this.node.children[i]; this.setItemPosition(child, prev, false, i == 0); prev = child; } } else { for (let i = 0; i < -offset; i++) { if (this.headerLoop) { this.pushToHeader(); } else if (this.footerLoop) { this.pushToHeader(); } else { if (this.vertical && this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM || this.horizontal && this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { this.pushToHeader(true); this.pushToFooter(); } else { this.pushToFooter(true); this.pushToHeader(); } } } } let startIndex = this.headerIndex > 0 ? this.headerIndex : 0; if (startIndex + this.node.children.length > this.itemTotal) { startIndex += offset; } if (startIndex < 0) startIndex = 0; for (let i = 0; i < this.node.children.length; i++) { const child: any = this.node.children[i]; if (this.headerLoop || this.footerLoop) { if (startIndex > this.itemTotal - 1) { startIndex = 0; } } child["__index"] = startIndex; startIndex++; if (refreshLastItem) { this.notifyRefreshItem(child); } } this.scrollView.stopAutoScroll(); this.scrollView.startAutoScroll(); } else { for (let i = 0; i < this.node.children.length; i++) { if (this.vertical) { if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { this.pushToFooter(); } else { this.pushToHeader(); } } else { if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { this.pushToFooter(); } else { this.pushToHeader(); } } } } } protected createItems(count: number, refreshLastItem: boolean = false) { // 有多余的item 需要删除 不处理 if (this.node.children.length > count) { this.removeItems(count); return; } if (!this.needAddPrefab()) { // 已经固定item总数 不处理 if (this._maxPrefabTotal > 0 && this._maxPrefabTotal == this.node.children.length) { return; } } let total = count - this.node.children.length; //计算当前应该创建的总数 for (let i = 0; i < total; i++) { let child: any = cc.instantiate(this.prefab); const transform = child; this.setAndSaveSizeAndScale(transform); child["__index"] = this.node.children.length; this.node.addChild(child); var reverse = false; var index = this.node.children.length - 2; var relative; if (child["__index"] == 0) { relative = this.footer; } else { relative = this.node.children[index]; } child.on(cc.Node.EventType.SIZE_CHANGED, () => { this.onChangeChildSize(transform); }, this, true); child.on(cc.Node.EventType.SCALE_CHANGED, (type: any) => { this.onChangeChildScale(transform); }, this, true); if (refreshLastItem) { this.notifyRefreshItem(child); } this.setItemPosition(child, relative, reverse, child["__index"] == 0); if (!this.needAddPrefab()) { this._maxPrefabTotal = this.node.children.length; console.log("已固定item数量", this._maxPrefabTotal); break; } } } protected needAddPrefab() { const self = this.vertical ? this.contentSize.height : this.contentSize.width; if (self > 0) { // 当尺寸改变时 重新计算prefab的数量 const view = this.vertical ? this.view.height : this.view.width; if (self < view * this.multiple) { return true; } } return false; } protected async onChangeChildSize(item: cc.Node) { const node: any = item; if (this.groupItemTotal > 1) { const __size = node["__size"]; item.setContentSize(__size); console.warn("表格布局不支持动态修改 Size,如果你非要修改,那你把我注释掉看效果"); return; } if (this.stretchLock.index == node["__index"]) { this.scrollToIndex(this.stretchLock.index!, this.stretchLock.timeInSecond, this.stretchLock.boundary, this.stretchLock.reverse); } this.resetStrectchItems(); } protected async onChangeChildScale(item: cc.Node) { if (!this.affectedByScale) return; const node: any = item; if (this.groupItemTotal > 1) { const __scale = node["__scale"]; item.setScale(__scale); // console.warn("表格布局不支持动态修改 Scale,如果你非要修改,那你把我注释掉看效果") return; } if (this.stretchLock.index == node["__index"]) { this.scrollToIndex(this.stretchLock.index!, this.stretchLock.timeInSecond, this.stretchLock.boundary, this.stretchLock.reverse); } this.resetStrectchItems(); } protected resetStrectchItems() { if (!isNaN(this.stretchLock.index!)) { const index = this.node.children.findIndex((item: any) => item["__index"] == this.stretchLock.index); if (index != -1) { for (let i = index; i >= 0; i--) { const item = this.node.children[i]; if (i == index) continue; if (i < index) { this.setItemPosition(item, this.node.children[i + 1], true); } } for (let i = index; i < this.node.children.length; i++) { const item = this.node.children[i]; if (i == index) continue; this.setItemPosition(item, this.node.children[i - 1]); } return; } } if (this.scrollDirection == ScrollDirection.HEADER) { this.unschedule(this.stretchToFooter); this.scheduleOnce(this.stretchToFooter); } else { this.unschedule(this.stretchToHeader); this.scheduleOnce(this.stretchToHeader); } } private stretchToHeader() { for (let i = this.node.children.length - 1; i >= 0; i--) { const item = this.node.children[i]; if (i == this.node.children.length - 1) continue; this.setItemPosition(item, this.node.children[i + 1], true); } } private stretchToFooter() { for (let i = 0; i < this.node.children.length; i++) { const item = this.node.children[i]; if (i == 0) continue; this.setItemPosition(item, this.node.children[i - 1]); } } /** 删除多余的item */ protected removeItems(count: number) { // 有多余的item 需要删除 let length = this.node.children.length - count; // 删除掉多余的item for (let i = 0; i < length; i++) { var child = this.node.children[this.node.children.length - 1]; child.off(cc.Node.EventType.SIZE_CHANGED); child.off(cc.Node.EventType.SCALE_CHANGED); this.node.removeChild(child); child.destroy(); } } protected addEventListener() { this.node.on(cc.Node.EventType.POSITION_CHANGED, this.onPositionChanged, this); } protected removeEventListener() { this.node.off(cc.Node.EventType.POSITION_CHANGED, this.onPositionChanged, this); } /** 重新计算当前所有Item的位置 */ protected resetChilds(start: boolean = false) { if (this.vertical && this.fixedItemHeight <= this.view.height || !this.vertical && this.fixedItemWidth <= this.view.width) { let x = this.getStartX(this.header); let y = this.getStartY(this.header); this.header && this.header.setPosition(new cc.Vec3(x, y)); } if (start) { if (this.vertical) { let x = this.getStartX(this.header); this.header && this.header.setPosition(new cc.Vec3(x, this.header.position.y)); } else { let y = this.getStartY(this.header); this.header && this.header.setPosition(new cc.Vec3(this.header.position.x, y)); } } this.stretchToFooter(); if (!start) { this.scrollView.startAutoScroll(); } } protected onTouchBegin() { this.stretchLock = {}; } protected getUsedScaleValue(value: number) { return this.affectedByScale ? Math.abs(value) : 1; } protected getScaleWidth(trans: cc.Node | null): number { if (!trans) return 0; const size = (trans as any)["__runtime_size"]; const width = size ? size.width : trans.width; return width * this.getUsedScaleValue(trans.scaleX); } protected getScaleHeight(trans: cc.Node | null): number { if (!trans) return 0; const size = (trans as any)["__runtime_size"]; const height = size ? size.height : trans.height; return height * this.getUsedScaleValue(trans.scaleY); } protected onPositionChanged() { if (this.isRestart) return; if (this.vertical) { if (this.scrollView.prevLocation.y < this.scrollView.location.y) { this.scrollDirection = ScrollDirection.FOOTER; } else if (this.scrollView.prevLocation.y > this.scrollView.location.y) { this.scrollDirection = ScrollDirection.HEADER; } else { this.scrollDirection = ScrollDirection.NONE; } } else { if (this.scrollView.prevLocation.x > this.scrollView.location.x) { this.scrollDirection = ScrollDirection.FOOTER; } else if (this.scrollView.prevLocation.x < this.scrollView.location.x) { this.scrollDirection = ScrollDirection.HEADER; } else { this.scrollDirection = ScrollDirection.NONE; } } if (this.vertical) { for (let i = 0; i < this.node.children.length; i++) { let isOfBoundary = Math.abs(this.prevPos.y - this.node.position.y) > EPSILON; if (!isOfBoundary) continue; if (this.prevPos.y < this.node.position.y) { this.pushToFooter(); } else if (this.prevPos.y > this.node.position.y) { this.pushToHeader(); } } } else { for (let i = 0; i < this.node.children.length; i++) { let isOfBoundary = Math.abs(this.prevPos.x - this.node.position.x) > EPSILON; if (!isOfBoundary) continue; if (this.prevPos.x > this.node.position.x) { this.pushToFooter(); } else if (this.prevPos.x < this.node.position.x) { this.pushToHeader(); } } } this.prevPos = this.node.position.clone(); } /** 向尾部填充 force如果为true 则强制填充 */ protected pushToFooter(force: boolean = false) { if (this.vertical) { var headerHeight = this.header && this.header.height || 0; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (force || this.headerBoundary - this.paddingTop > this.viewHeaderBoundary + headerHeight) { this.pushToFooterHandler(); } } else { if (force || this.footerBoundary - this.paddingTop > this.viewHeaderBoundary + headerHeight) { this.pushToHeaderHandler(); } } } else { var headerWidth = this.header && this.header.width || 0; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (force || this.headerBoundary + this.paddingLeft < this.viewHeaderBoundary - headerWidth) { this.pushToFooterHandler(); } } else { if (force || this.footerBoundary + this.paddingLeft < this.viewHeaderBoundary - headerWidth) { this.pushToHeaderHandler(); } } } } /** 向头部填充 force如果为true 则强制填充 */ protected pushToHeader(force: boolean = false) { if (this.vertical) { var footerHeight = this.footer && this.footer.height || 0; if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { if (force || this.footerBoundary + this.paddingBottom < this.viewFooterBoundary - footerHeight) { this.pushToHeaderHandler(); } } else { if (force || this.headerBoundary + this.paddingBottom < this.viewFooterBoundary - footerHeight) { this.pushToFooterHandler(); } } } else { var footerWidth = this.footer && this.footer.width || 0; if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { if (force || this.footerBoundary - this.paddingRight > this.viewFooterBoundary + footerWidth) { this.pushToHeaderHandler(); } } else { if (force || this.headerBoundary - this.paddingRight > this.viewFooterBoundary + footerWidth) { this.pushToFooterHandler(); } } } } protected pushToFooterHandler() { var node: any = this.header; let loop; if (this.vertical) { loop = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.footerLoop : this.headerLoop; } else { loop = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.footerLoop : this.headerLoop; } if (loop) { if (this.footerIndex >= this.itemTotal - 1) { node["__index"] = 0; } else { node["__index"] = this.footerIndex + 1; } } else { if (!this.footer || this.footerIndex >= this.itemTotal - 1) return; node["__index"] = this.footerIndex + 1; } if (node["__index"] >= 0 && node["__index"] < this.currentCreateItemTotal) { this.notifyRefreshItem(node); } this.setItemPosition(this.header!, this.footer!); this.header.setSiblingIndex(this.node.children.length); } protected pushToHeaderHandler() { var node: any = this.footer; let loop; if (this.vertical) { loop = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.headerLoop : this.footerLoop; } else { loop = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.headerLoop : this.footerLoop; } // 对其头部 if (!loop && this.headerIndex == 0) { // 判断是否是起始位置 var accommodate; if (this.vertical) { accommodate = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.isAccommodateByLeft(this.header!) : this.isAccommodateByRight(this.header!); } else { accommodate = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.isAccommodateByTop(this.header!) : this.isAccommodateByBottom(this.header!); } if (accommodate) { this.resetChilds(true); } } if (loop) { if (this.headerIndex == 0) { node["__index"] = this.itemTotal - 1; } else { node["__index"] = this.headerIndex - 1; } } else { if (!this.header || this.headerIndex == 0) return; node["__index"] = this.headerIndex - 1; } if (node["__index"] >= 0 && node["__index"] < this.currentCreateItemTotal) { this.notifyRefreshItem(node); } this.setItemPosition(this.footer, this.header, true); this.footer.setSiblingIndex(0); } /** 通知给定的node刷新数据 */ protected notifyRefreshItem(target: Node) { cc.Component.EventHandler.emitEvents(this.refreshItemEvents, target, (target as any)['__index']); } // public OnTouchEvent(): void { this.scrollView.node.on(cc.Node.EventType.TOUCH_START, this.scrollView._onTouchBegan, this.scrollView, true); this.scrollView.node.on(cc.Node.EventType.TOUCH_MOVE, this.scrollView._onTouchMoved, this.scrollView, true); this.scrollView.node.on(cc.Node.EventType.TOUCH_END, this.scrollView._onTouchEnded, this.scrollView, true); this.scrollView.node.on(cc.Node.EventType.TOUCH_CANCEL, this.scrollView._onTouchCancelled, this.scrollView, true); } public OffTouchEvent(): void { this.scrollView.node.off(cc.Node.EventType.TOUCH_START, this.scrollView._onTouchBegan, this.scrollView, true); this.scrollView.node.off(cc.Node.EventType.TOUCH_MOVE, this.scrollView._onTouchMoved, this.scrollView, true); this.scrollView.node.off(cc.Node.EventType.TOUCH_END, this.scrollView._onTouchEnded, this.scrollView, true); this.scrollView.node.off(cc.Node.EventType.TOUCH_CANCEL, this.scrollView._onTouchCancelled, this.scrollView, true); } }