Compare commits

..

No commits in common. "main" and "2.0.0" have entirely different histories.
main ... 2.0.0

4 changed files with 14 additions and 213 deletions

View File

@ -299,24 +299,6 @@ class _scroll_view extends ScrollView {
} }
} }
class _yx_node_pool extends NodePool {
getAtIdx(indexPath: YXIndexPath, ...args: any[]): Node | null {
const nodes: Node[] = this['_pool']
for (let index = 0; index < nodes.length; index++) {
const obj = nodes[index];
let comp = obj.getComponent(_yx_node_element_comp)
if (comp && comp.attributes.indexPath.equals(indexPath)) {
nodes.splice(index, 1)
// @ts-ignore
const handler = this.poolHandlerComp ? obj.getComponent(this.poolHandlerComp) : null;
if (handler && handler.reuse) { handler.reuse(arguments); }
return obj
}
}
return null
}
}
/** /**
* *
*/ */
@ -660,7 +642,7 @@ export class YXCollectionView extends Component {
registerCell(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { registerCell(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) {
let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Cell' let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Cell'
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = new _yx_node_pool(poolComp) let pool = new NodePool(poolComp)
this.pools.set(identifier, pool) this.pools.set(identifier, pool)
this.makers.set(identifier, maker) this.makers.set(identifier, maker)
} }
@ -671,7 +653,7 @@ export class YXCollectionView extends Component {
registerSupplementary(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { registerSupplementary(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) {
let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Supplementary' let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Supplementary'
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = new _yx_node_pool(poolComp) let pool = new NodePool(poolComp)
this.pools.set(identifier, pool) this.pools.set(identifier, pool)
this.makers.set(identifier, maker) this.makers.set(identifier, maker)
} }
@ -689,21 +671,19 @@ export class YXCollectionView extends Component {
/** /**
* cell * cell
* @param identifier * @param identifier
* @param indexPath indexPath ()
*/ */
dequeueReusableCell(identifier: string, indexPath: YXIndexPath = null): Node { dequeueReusableCell(identifier: string): Node {
return this._dequeueReusableElement(identifier, 'Cell', indexPath) return this._dequeueReusableElement(identifier, 'Cell')
} }
/** /**
* supplementary * supplementary
* @param identifier * @param identifier
* @param indexPath indexPath ()
*/ */
dequeueReusableSupplementary(identifier: string, indexPath: YXIndexPath = null): Node { dequeueReusableSupplementary(identifier: string): Node {
return this._dequeueReusableElement(identifier, 'Supplementary', indexPath) return this._dequeueReusableElement(identifier, 'Supplementary')
} }
private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory, indexPath: YXIndexPath = null) { private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory) {
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = this.pools.get(identifier) let pool = this.pools.get(identifier)
if (pool == null) { if (pool == null) {
@ -711,11 +691,6 @@ export class YXCollectionView extends Component {
} }
let result: Node = null let result: Node = null
// 尝试从重用池获取 (牺牲一点性能,尝试通过 indexPath 获取对应的节点,防止刷新闪烁的问题)
if (result == null && indexPath && pool instanceof _yx_node_pool) {
result = pool.getAtIdx(indexPath)
}
// 尝试从重用池获取 // 尝试从重用池获取
if (result == null) { if (result == null) {
result = pool.get() result = pool.get()

View File

@ -1,140 +0,0 @@
import { math, UITransform, warn } from "cc";
import { YXCollectionView, YXIndexPath, YXLayout, YXLayoutAttributes } from "./yx-collection-view";
export class GridLayout extends YXLayout {
/**
*
*/
itemSize: math.Size = new math.Size(100, 100)
/**
*
*/
horizontalSpacing: number = 0
/**
*
*/
verticalSpacing: number = 0
/**
*
* 0 1 2
*/
alignment: number = 1
/**
*
*/
protected getMaxItemsPerRow(collectionView: YXCollectionView): number {
if (this._maxItemsPerRow == null) {
let num = 1
const width = collectionView.node.getComponent(UITransform).contentSize.width
while ((num * this.itemSize.width + (num - 1) * this.horizontalSpacing) <= width) { num++ }
num = Math.max(1, num - 1)
this._maxItemsPerRow = num
}
return this._maxItemsPerRow
}
protected _maxItemsPerRow: number = null
prepare(collectionView: YXCollectionView): void {
if (collectionView.scrollDirection === YXCollectionView.ScrollDirection.VERTICAL) {
this._prepare_vertical(collectionView)
return
}
if (collectionView.scrollDirection === YXCollectionView.ScrollDirection.HORIZONTAL) {
warn(`GridLayout 仅支持垂直方向排列`)
this._prepare_vertical(collectionView)
return
}
}
protected _prepare_vertical(collectionView: YXCollectionView) {
collectionView.scrollView.horizontal = false
collectionView.scrollView.vertical = true
let attrs: YXLayoutAttributes[] = []
let contentSize = collectionView.node.getComponent(UITransform).contentSize.clone()
// 容器宽度
const width = contentSize.width
// 计算每行最多可以放多少个节点
this._maxItemsPerRow = null
let num = this.getMaxItemsPerRow(collectionView)
// 根据设置的对齐方式计算左边距
let left = 0
if (this.alignment == 1) {
let maxWidth = (num * this.itemSize.width + (num - 1) * this.horizontalSpacing) // 每行节点总宽度
left = (width - maxWidth) * 0.5
}
if (this.alignment == 2) {
let maxWidth = (num * this.itemSize.width + (num - 1) * this.horizontalSpacing) // 每行节点总宽度
left = width - maxWidth
}
const numberOfSections = collectionView.getNumberOfSections()
if (numberOfSections > 1) { warn(`GridLayout 暂时不支持分区模式`) }
const numberOfItems = collectionView.getNumberOfItems(0)
for (let index = 0; index < numberOfItems; index++) {
// 计算这个节点是第几行
let row = Math.floor(index / num)
// 计算这个节点是第几列
let column = index % num
// 计算节点 origin
let x = left + (this.itemSize.width + this.horizontalSpacing) * column
let y = (this.itemSize.height + this.verticalSpacing) * row
let attr = YXLayoutAttributes.layoutAttributesForCell(new YXIndexPath(0, index))
attr.frame.x = x
attr.frame.y = y
attr.frame.width = this.itemSize.width
attr.frame.height = this.itemSize.height
attrs.push(attr)
// 更新内容高度
contentSize.height = Math.max(contentSize.height, attr.frame.yMax)
}
this.attributes = attrs
this.contentSize = contentSize
}
initOffset(collectionView: YXCollectionView): void {
collectionView.scrollView.scrollToTop()
}
layoutAttributesForElementsInRect(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
return this.visibleElementsInRect(rect, collectionView)
}
/**
*
* @see YXLayout.layoutAttributesForElementsInRect
*/
protected visibleElementsInRect(rect: math.Rect, collectionView: YXCollectionView) {
if (this.attributes.length <= 100) { return this.attributes } // 少量数据就不查了,直接返回全部
// 根据当前范围直接计算出一个区间
const startRow = Math.floor(rect.y / (this.itemSize.height + this.verticalSpacing))
const endRow = Math.ceil(rect.yMax / (this.itemSize.height + this.verticalSpacing))
// 计算每行最多可以放多少个节点
let num = this.getMaxItemsPerRow(collectionView)
// 计算索引区间
const startIdx = startRow * num
const endIdx = endRow * num
// 只返回区间节点的布局属性
return this.attributes.slice(startIdx, endIdx)
}
}

View File

@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "02a96aac-8c52-4201-b8af-c7ed49aae6d4",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@ -296,24 +296,6 @@ class _scroll_view extends ScrollView {
} }
} }
class _yx_node_pool extends NodePool {
getAtIdx(indexPath: YXIndexPath, ...args: any[]): Node | null {
const nodes: Node[] = this['_pool']
for (let index = 0; index < nodes.length; index++) {
const obj = nodes[index];
let comp = obj.getComponent(_yx_node_element_comp)
if (comp && comp.attributes.indexPath.equals(indexPath)) {
nodes.splice(index, 1)
// @ts-ignore
const handler = this.poolHandlerComp ? obj.getComponent(this.poolHandlerComp) : null;
if (handler && handler.reuse) { handler.reuse(arguments); }
return obj
}
}
return null
}
}
/** /**
* *
*/ */
@ -659,7 +641,7 @@ export class YXCollectionView extends Component {
registerCell(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { registerCell(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) {
let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Cell' let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Cell'
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = new _yx_node_pool(poolComp) let pool = new NodePool(poolComp)
this.pools.set(identifier, pool) this.pools.set(identifier, pool)
this.makers.set(identifier, maker) this.makers.set(identifier, maker)
} }
@ -670,7 +652,7 @@ export class YXCollectionView extends Component {
registerSupplementary(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) { registerSupplementary(identifier: string, maker: () => Node, poolComp: (new (...args: any[]) => YXCollectionViewCell) | string | null = null) {
let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Supplementary' let elementCategory: typeof YXLayoutAttributes.prototype.elementCategory = 'Supplementary'
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = new _yx_node_pool(poolComp) let pool = new NodePool(poolComp)
this.pools.set(identifier, pool) this.pools.set(identifier, pool)
this.makers.set(identifier, maker) this.makers.set(identifier, maker)
} }
@ -688,21 +670,19 @@ export class YXCollectionView extends Component {
/** /**
* cell * cell
* @param identifier * @param identifier
* @param indexPath indexPath ()
*/ */
dequeueReusableCell(identifier: string, indexPath: YXIndexPath = null): Node { dequeueReusableCell(identifier: string): Node {
return this._dequeueReusableElement(identifier, 'Cell', indexPath) return this._dequeueReusableElement(identifier, 'Cell')
} }
/** /**
* supplementary * supplementary
* @param identifier * @param identifier
* @param indexPath indexPath ()
*/ */
dequeueReusableSupplementary(identifier: string, indexPath: YXIndexPath = null): Node { dequeueReusableSupplementary(identifier: string): Node {
return this._dequeueReusableElement(identifier, 'Supplementary', indexPath) return this._dequeueReusableElement(identifier, 'Supplementary')
} }
private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory, indexPath: YXIndexPath = null) { private _dequeueReusableElement(identifier: string, elementCategory: typeof YXLayoutAttributes.prototype.elementCategory) {
identifier = elementCategory + identifier identifier = elementCategory + identifier
let pool = this.pools.get(identifier) let pool = this.pools.get(identifier)
if (pool == null) { if (pool == null) {
@ -710,11 +690,6 @@ export class YXCollectionView extends Component {
} }
let result: Node = null let result: Node = null
// 尝试从重用池获取 (牺牲一点性能,尝试通过 indexPath 获取对应的节点,防止刷新闪烁的问题)
if (result == null && indexPath && pool instanceof _yx_node_pool) {
result = pool.getAtIdx(indexPath)
}
// 尝试从重用池获取 // 尝试从重用池获取
if (result == null) { if (result == null) {
result = pool.get() result = pool.get()