@ives_xxz/framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/FW.d.ts +1845 -0
  2. package/FW.d.ts.meta +6 -0
  3. package/Framework.ts +148 -0
  4. package/Framework.ts.meta +10 -0
  5. package/README.md +93 -0
  6. package/README.md.meta +6 -0
  7. package/animation/FWAnimation.ts +13 -0
  8. package/animation/FWAnimation.ts.meta +10 -0
  9. package/animation/FWSkeleton.ts +176 -0
  10. package/animation/FWSkeleton.ts.meta +10 -0
  11. package/animation/FWTween.ts +60 -0
  12. package/animation/FWTween.ts.meta +10 -0
  13. package/animation.meta +13 -0
  14. package/component/FWVirtualViewComponent.ts +2080 -0
  15. package/component/FWVirtualViewComponent.ts.meta +10 -0
  16. package/component.meta +13 -0
  17. package/config/FWAssetConfig.ts +7 -0
  18. package/config/FWAssetConfig.ts.meta +10 -0
  19. package/config.meta +13 -0
  20. package/controller/FWLayerController.ts +236 -0
  21. package/controller/FWLayerController.ts.meta +10 -0
  22. package/controller.meta +13 -0
  23. package/data/FWData.ts +10 -0
  24. package/data/FWData.ts.meta +10 -0
  25. package/data.meta +13 -0
  26. package/define/FWEventDefine.ts +26 -0
  27. package/define/FWEventDefine.ts.meta +10 -0
  28. package/define/FWSystemDefine.ts +133 -0
  29. package/define/FWSystemDefine.ts.meta +10 -0
  30. package/define.meta +13 -0
  31. package/entry/FWEntry.ts +196 -0
  32. package/entry/FWEntry.ts.meta +10 -0
  33. package/entry.meta +13 -0
  34. package/expand/FWCocosExpand.ts +73 -0
  35. package/expand/FWCocosExpand.ts.meta +10 -0
  36. package/expand/FWDecorator.ts +256 -0
  37. package/expand/FWDecorator.ts.meta +10 -0
  38. package/expand/FWRollingViewNesting.ts +191 -0
  39. package/expand/FWRollingViewNesting.ts.meta +10 -0
  40. package/expand/FWTweenExpand.ts +44 -0
  41. package/expand/FWTweenExpand.ts.meta +10 -0
  42. package/expand.meta +13 -0
  43. package/item/FWVirtualListItem.ts +150 -0
  44. package/item/FWVirtualListItem.ts.meta +10 -0
  45. package/item.meta +13 -0
  46. package/language/FWLanguage.ts +69 -0
  47. package/language/FWLanguage.ts.meta +10 -0
  48. package/language/FWLanguageLabelLocalize.ts +144 -0
  49. package/language/FWLanguageLabelLocalize.ts.meta +10 -0
  50. package/language/FWLanguageSkeletonLocalize.ts +106 -0
  51. package/language/FWLanguageSkeletonLocalize.ts.meta +10 -0
  52. package/language/FWLanguageSpriteLocalize.ts +81 -0
  53. package/language/FWLanguageSpriteLocalize.ts.meta +10 -0
  54. package/language.meta +13 -0
  55. package/layer/FWLayer.ts +13 -0
  56. package/layer/FWLayer.ts.meta +10 -0
  57. package/layer.meta +13 -0
  58. package/log/FWLog.ts +115 -0
  59. package/log/FWLog.ts.meta +10 -0
  60. package/log.meta +13 -0
  61. package/logic/FWLogic.ts +10 -0
  62. package/logic/FWLogic.ts.meta +10 -0
  63. package/logic.meta +13 -0
  64. package/machine/FWAnimationMachine.ts +28 -0
  65. package/machine/FWAnimationMachine.ts.meta +10 -0
  66. package/machine/FWStateMachine.ts +75 -0
  67. package/machine/FWStateMachine.ts.meta +10 -0
  68. package/machine.meta +13 -0
  69. package/manager/FWAnimationManager.ts +128 -0
  70. package/manager/FWAnimationManager.ts.meta +10 -0
  71. package/manager/FWAssetManager.ts +349 -0
  72. package/manager/FWAssetManager.ts.meta +10 -0
  73. package/manager/FWAudioManager.ts +289 -0
  74. package/manager/FWAudioManager.ts.meta +10 -0
  75. package/manager/FWBundleManager.ts +91 -0
  76. package/manager/FWBundleManager.ts.meta +10 -0
  77. package/manager/FWComponentManager.ts +25 -0
  78. package/manager/FWComponentManager.ts.meta +10 -0
  79. package/manager/FWEngineManager.ts +63 -0
  80. package/manager/FWEngineManager.ts.meta +10 -0
  81. package/manager/FWEventManager.ts +275 -0
  82. package/manager/FWEventManager.ts.meta +10 -0
  83. package/manager/FWHotUpdateManager.ts +213 -0
  84. package/manager/FWHotUpdateManager.ts.meta +10 -0
  85. package/manager/FWLanguageManager.ts +116 -0
  86. package/manager/FWLanguageManager.ts.meta +10 -0
  87. package/manager/FWLayerManager.ts +490 -0
  88. package/manager/FWLayerManager.ts.meta +10 -0
  89. package/manager/FWManager.ts +8 -0
  90. package/manager/FWManager.ts.meta +10 -0
  91. package/manager/FWObjectManager.ts +91 -0
  92. package/manager/FWObjectManager.ts.meta +10 -0
  93. package/manager/FWResManager.ts +171 -0
  94. package/manager/FWResManager.ts.meta +10 -0
  95. package/manager/FWSocketManager.ts +94 -0
  96. package/manager/FWSocketManager.ts.meta +10 -0
  97. package/manager/FWStateManager.ts +102 -0
  98. package/manager/FWStateManager.ts.meta +10 -0
  99. package/manager/FWTaskManager.ts +38 -0
  100. package/manager/FWTaskManager.ts.meta +10 -0
  101. package/manager/FWTimeManager.ts +473 -0
  102. package/manager/FWTimeManager.ts.meta +10 -0
  103. package/manager/FWUiManager.ts +164 -0
  104. package/manager/FWUiManager.ts.meta +10 -0
  105. package/manager.meta +13 -0
  106. package/package.json +17 -0
  107. package/package.json.meta +6 -0
  108. package/scene/FWScene.ts +25 -0
  109. package/scene/FWScene.ts.meta +10 -0
  110. package/scene.meta +13 -0
  111. package/service/FWService.ts +7 -0
  112. package/service/FWService.ts.meta +10 -0
  113. package/service/http/FWHttp.ts +70 -0
  114. package/service/http/FWHttp.ts.meta +10 -0
  115. package/service/http.meta +13 -0
  116. package/service/socket/FWSocket.ts +236 -0
  117. package/service/socket/FWSocket.ts.meta +10 -0
  118. package/service/socket/FWSocketHandle.ts +17 -0
  119. package/service/socket/FWSocketHandle.ts.meta +10 -0
  120. package/service/socket/FWSocketSender.ts +16 -0
  121. package/service/socket/FWSocketSender.ts.meta +10 -0
  122. package/service/socket.meta +13 -0
  123. package/service.meta +13 -0
  124. package/state/FWState.ts +8 -0
  125. package/state/FWState.ts.meta +10 -0
  126. package/state.meta +13 -0
  127. package/utils/FWLodash.ts +105 -0
  128. package/utils/FWLodash.ts.meta +10 -0
  129. package/utils/FWMask.ts +222 -0
  130. package/utils/FWMask.ts.meta +10 -0
  131. package/utils/FWObject.ts +22 -0
  132. package/utils/FWObject.ts.meta +10 -0
  133. package/utils/FWObjectPool.ts +178 -0
  134. package/utils/FWObjectPool.ts.meta +10 -0
  135. package/utils/FWQueue.ts +47 -0
  136. package/utils/FWQueue.ts.meta +10 -0
  137. package/utils/FWTask.ts +223 -0
  138. package/utils/FWTask.ts.meta +10 -0
  139. package/utils.meta +13 -0
@@ -0,0 +1,2080 @@
1
+ import { FWSystemDefine } from '../define/FWSystemDefine';
2
+ import FWListItem from '../item/FWVirtualListItem';
3
+ import FWLog from '../log/FWLog';
4
+
5
+ const { ccclass, property, disallowMultiple, menu, executionOrder, requireComponent } =
6
+ cc._decorator;
7
+
8
+ @ccclass
9
+ @disallowMultiple()
10
+ @menu('CustomComponent/FWVirtualViewComponent')
11
+ @requireComponent(cc.ScrollView)
12
+ //脚本生命周期回调的执行优先级。小于 0 的脚本将优先执行,大于 0 的脚本将最后执行。该优先级只对 onLoad, onEnable, start, update 和 lateUpdate 有效,对 onDisable 和 onDestroy 无效。
13
+ @executionOrder(-5000)
14
+ export default class FWVirtualViewComponent
15
+ extends cc.Component
16
+ implements FW.VirtualViewComponent
17
+ {
18
+ set count(count: number) {
19
+ this.numItems = count;
20
+ }
21
+
22
+ set templatePrefab(prefab: cc.Prefab) {
23
+ this.tmpPrefab = prefab;
24
+ this._init();
25
+ this.numItems = this.numItems;
26
+ }
27
+
28
+ set templateNode(node: cc.Node) {
29
+ this.tmpNode = node;
30
+ this._init();
31
+ this.numItems = this.numItems;
32
+ }
33
+
34
+ onRender?: FW.VirtualViewListener;
35
+ onPageChange?: FW.VirtualViewListener;
36
+ onSelected?: FW.VirtualViewListener;
37
+
38
+ //模板类型
39
+ @property({
40
+ type: cc.Enum(FWSystemDefine.FWScrollViewTemplateType),
41
+ tooltip: CC_DEV && '模板类型',
42
+ })
43
+ private templateType: FWSystemDefine.FWScrollViewTemplateType =
44
+ FWSystemDefine.FWScrollViewTemplateType.PREFAB;
45
+ //模板Item(Node)
46
+ @property({
47
+ type: cc.Node,
48
+ tooltip: CC_DEV && '模板Item',
49
+ visible() {
50
+ return this.templateType == FWSystemDefine.FWScrollViewTemplateType.NODE;
51
+ },
52
+ })
53
+ tmpNode: cc.Node = null;
54
+ //模板Item(Prefab)
55
+ @property({
56
+ type: cc.Prefab,
57
+ tooltip: CC_DEV && '模板Item',
58
+ visible() {
59
+ return this.templateType == FWSystemDefine.FWScrollViewTemplateType.PREFAB;
60
+ },
61
+ })
62
+ tmpPrefab: cc.Prefab = null;
63
+ //滑动模式
64
+ @property()
65
+ private _slideMode: FWSystemDefine.FWScrollViewSlideType =
66
+ FWSystemDefine.FWScrollViewSlideType.NORMAL;
67
+ @property({
68
+ type: cc.Enum(FWSystemDefine.FWScrollViewSlideType),
69
+ tooltip: CC_DEV && '滑动模式',
70
+ })
71
+ set slideMode(val: FWSystemDefine.FWScrollViewSlideType) {
72
+ this._slideMode = val;
73
+ }
74
+ get slideMode() {
75
+ return this._slideMode;
76
+ }
77
+ //翻页作用距离
78
+ @property({
79
+ type: cc.Float,
80
+ range: [0, 1, 0.1],
81
+ tooltip: CC_DEV && '翻页作用距离',
82
+ slide: true,
83
+ visible() {
84
+ return this._slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE;
85
+ },
86
+ })
87
+ public pageDistance: number = 0.3;
88
+
89
+ //是否为虚拟列表(动态列表)
90
+ @property()
91
+ private _virtual: boolean = true;
92
+ @property({
93
+ type: cc.Boolean,
94
+ tooltip: CC_DEV && '是否为虚拟列表(动态列表)',
95
+ })
96
+ set virtual(val: boolean) {
97
+ if (val != null) this._virtual = val;
98
+ if (!CC_DEV && this._numItems != 0) {
99
+ this._onScrolling();
100
+ }
101
+ }
102
+ get virtual() {
103
+ return this._virtual;
104
+ }
105
+ //是否为循环列表
106
+ @property({
107
+ tooltip: CC_DEV && '是否为循环列表',
108
+ visible() {
109
+ let val: boolean =
110
+ /*this.virtual &&*/ this.slideMode == FWSystemDefine.FWScrollViewSlideType.NORMAL;
111
+ if (!val) this.cyclic = false;
112
+ return val;
113
+ },
114
+ })
115
+ public cyclic: boolean = false;
116
+ //缺省居中
117
+ @property({
118
+ tooltip: CC_DEV && 'Item数量不足以填满Content时,是否居中显示Item(不支持Grid布局)',
119
+ visible() {
120
+ return this.virtual;
121
+ },
122
+ })
123
+ public lackCenter: boolean = false;
124
+ //缺省可滑动
125
+ @property({
126
+ tooltip: CC_DEV && 'Item数量不足以填满Content时,是否可滑动',
127
+ visible() {
128
+ let val: boolean = this.virtual && !this.lackCenter;
129
+ if (!val) this.lackSlide = false;
130
+ return val;
131
+ },
132
+ })
133
+ public lackSlide: boolean = false;
134
+ //刷新频率
135
+ @property({ type: cc.Integer })
136
+ private _updateRate: number = 0;
137
+ @property({
138
+ type: cc.Integer,
139
+ range: [0, 6, 1],
140
+ tooltip: CC_DEV && '刷新频率(值越大刷新频率越低、性能越高)',
141
+ slide: true,
142
+ })
143
+ set updateRate(val: number) {
144
+ if (val >= 0 && val <= 6) {
145
+ this._updateRate = val;
146
+ }
147
+ }
148
+ get updateRate() {
149
+ return this._updateRate;
150
+ }
151
+ //分帧渲染(每帧渲染的Item数量(<=0时关闭分帧渲染))
152
+ @property({
153
+ type: cc.Integer,
154
+ range: [0, 12, 1],
155
+ tooltip: CC_DEV && '逐帧渲染时,每帧渲染的Item数量(<=0时关闭分帧渲染)',
156
+ slide: true,
157
+ })
158
+ public frameByFrameRenderNum: number = 0;
159
+
160
+ //选择模式
161
+ @property({
162
+ type: cc.Enum(FWSystemDefine.FWScrollViewSelectedType),
163
+ tooltip: CC_DEV && '选择模式',
164
+ })
165
+ public selectedMode: FWSystemDefine.FWScrollViewSelectedType =
166
+ FWSystemDefine.FWScrollViewSelectedType.NONE;
167
+ @property({
168
+ tooltip: CC_DEV && '是否重复响应单选事件',
169
+ visible() {
170
+ return this.selectedMode == FWSystemDefine.FWScrollViewSelectedType.SINGLE;
171
+ },
172
+ })
173
+ public repeatEventSingle: boolean = false;
174
+
175
+ @property({ tooltip: CC_DEV && '是否刷新widget' })
176
+ public isUpdateWidget: boolean = true;
177
+
178
+ //当前选择id
179
+ private _selectedId: number = 0;
180
+ private _lastSelectedId: number;
181
+ private multSelected: number[];
182
+ set selectedId(val: number) {
183
+ let t: FWVirtualViewComponent = this;
184
+ let item: any;
185
+ switch (t.selectedMode) {
186
+ case FWSystemDefine.FWScrollViewSelectedType.SINGLE: {
187
+ if (!t.repeatEventSingle && val == t._selectedId) return;
188
+ item = t.getItemByListId(val);
189
+
190
+ if (t._selectedId >= 0) t._lastSelectedId = t._selectedId;
191
+ //如果<0则取消选择,把_lastSelectedId也置空吧,如果以后有特殊需求再改吧。
192
+ else t._lastSelectedId = null;
193
+ t._selectedId = val;
194
+
195
+ if (t._lastSelectedId >= 0 && t._lastSelectedId != t._selectedId) {
196
+ let lastItem: any = t.getItemByListId(t._lastSelectedId);
197
+ if (lastItem) {
198
+ lastItem.getComponent(FWListItem).selected = false;
199
+ }
200
+ }
201
+ t.onSelected?.(
202
+ item,
203
+ val % this._actualNumItems,
204
+ t.selectedId == null ? null : t.selectedId % this._actualNumItems,
205
+ );
206
+ break;
207
+ }
208
+ case FWSystemDefine.FWScrollViewSelectedType.MULTIPLE: {
209
+ item = t.getItemByListId(val);
210
+ if (!item) return;
211
+ let listItem = item.getComponent(FWListItem);
212
+ if (t._selectedId >= 0) t._lastSelectedId = t._selectedId;
213
+ t._selectedId = val;
214
+ let bool: boolean = !listItem.selected;
215
+ listItem.selected = bool;
216
+ let sub: number = t.multSelected.indexOf(val);
217
+ if (bool && sub < 0) {
218
+ t.multSelected.push(val);
219
+ } else if (!bool && sub >= 0) {
220
+ t.multSelected.splice(sub, 1);
221
+ }
222
+ t.onSelected?.(
223
+ item,
224
+ val % this._actualNumItems,
225
+ t._lastSelectedId == null ? null : t._lastSelectedId % this._actualNumItems,
226
+ bool,
227
+ );
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ get selectedId() {
233
+ return this._selectedId;
234
+ }
235
+ private _forceUpdate: boolean = false;
236
+ private _align: number;
237
+ private _horizontalDir: number;
238
+ private _verticalDir: number;
239
+ private _startAxis: number;
240
+ private _alignCalcType: number;
241
+ public content: cc.Node;
242
+ private firstListId: number;
243
+ public displayItemNum: number;
244
+ private _updateDone: boolean = true;
245
+ private _updateCounter: number;
246
+ public _actualNumItems: number;
247
+ private _cyclicNum: number;
248
+ private _cyclicPos1: number;
249
+ private _cyclicPos2: number;
250
+ //列表数量
251
+ @property({
252
+ serializable: false,
253
+ })
254
+ private _numItems: number = 0;
255
+ set numItems(val: number) {
256
+ let t = this;
257
+ if (!t.checkInited(false)) return;
258
+ if (val == null || val < 0) {
259
+ FWLog.error('numItems set the wrong::', val);
260
+ return;
261
+ }
262
+ t._actualNumItems = t._numItems = val;
263
+ t._forceUpdate = true;
264
+
265
+ if (t._virtual) {
266
+ t._resizeContent();
267
+ if (t.cyclic) {
268
+ t._numItems = t._cyclicNum * t._numItems;
269
+ }
270
+ t._onScrolling();
271
+ if (!t.frameByFrameRenderNum && t.slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE)
272
+ t.curPageNum = t.nearestListId;
273
+ } else {
274
+ if (t.cyclic) {
275
+ t._resizeContent();
276
+ t._numItems = t._cyclicNum * t._numItems;
277
+ }
278
+ let layout: cc.Layout = t.content.getComponent(cc.Layout);
279
+ if (layout) {
280
+ layout.enabled = true;
281
+ }
282
+ t._delRedundantItem();
283
+
284
+ t.firstListId = 0;
285
+ if (t.frameByFrameRenderNum > 0) {
286
+ //先渲染几个出来
287
+ let len: number =
288
+ t.frameByFrameRenderNum > t._numItems ? t._numItems : t.frameByFrameRenderNum;
289
+ for (let n: number = 0; n < len; n++) {
290
+ t._createOrUpdateItem2(n);
291
+ }
292
+ if (t.frameByFrameRenderNum < t._numItems) {
293
+ t._updateCounter = t.frameByFrameRenderNum;
294
+ t._updateDone = false;
295
+ }
296
+ } else {
297
+ for (let n: number = 0; n < t._numItems; n++) {
298
+ t._createOrUpdateItem2(n);
299
+ }
300
+ t.displayItemNum = t._numItems;
301
+ }
302
+ }
303
+ }
304
+ get numItems() {
305
+ return this._actualNumItems;
306
+ }
307
+
308
+ private _inited: boolean = false;
309
+ private _scrollView: cc.ScrollView;
310
+ get scrollView() {
311
+ return this._scrollView;
312
+ }
313
+ private _layout: cc.Layout;
314
+ private _resizeMode: cc.Layout.ResizeMode;
315
+ private _topGap: number;
316
+ private _rightGap: number;
317
+ private _bottomGap: number;
318
+ private _leftGap: number;
319
+
320
+ private _columnGap: number;
321
+ private _lineGap: number;
322
+ private _colLineNum: number;
323
+
324
+ private _lastDisplayData: number[];
325
+ public displayData: any[];
326
+ private _pool: cc.NodePool;
327
+
328
+ private _itemTmp: any;
329
+ private _needUpdateWidget: boolean = false;
330
+ private _itemSize: cc.Size;
331
+ private _sizeType: boolean;
332
+
333
+ public _customSize: any;
334
+
335
+ private frameCount: number;
336
+ private _aniDelRuning: boolean = false;
337
+ private _aniDelCB: Function;
338
+ private _aniDelItem: any;
339
+ private _aniDelBeforePos: cc.Vec2;
340
+ private _aniDelBeforeScale: number;
341
+ private viewTop: number;
342
+ private viewRight: number;
343
+ private viewBottom: number;
344
+ private viewLeft: number;
345
+
346
+ private _doneAfterUpdate: boolean = false;
347
+
348
+ private elasticTop: number;
349
+ private elasticRight: number;
350
+ private elasticBottom: number;
351
+ private elasticLeft: number;
352
+
353
+ private scrollToListId: number;
354
+
355
+ private adhering: boolean = false;
356
+
357
+ private _adheringBarrier: boolean = false;
358
+ private nearestListId: number;
359
+
360
+ public curPageNum: number = 0;
361
+ private _beganPos: number;
362
+ private _scrollPos: number;
363
+ private curScrollIsTouch: boolean; //当前滑动是否为手动
364
+
365
+ private _scrollToListId: number;
366
+ private _scrollToEndTime: number;
367
+ private _scrollToSo: any;
368
+
369
+ private _lack: boolean;
370
+ private _allItemSize: number;
371
+ private _allItemSizeNoEdge: number;
372
+
373
+ private _scrollItem: any; //当前控制 ScrollView 滚动的 Item
374
+
375
+ //----------------------------------------------------------------------------
376
+
377
+ onLoad() {
378
+ this._init();
379
+ }
380
+
381
+ onDestroy() {
382
+ let t: any = this;
383
+ if (cc.isValid(t._itemTmp)) t._itemTmp.destroy();
384
+ if (cc.isValid(t.tmpNode)) t.tmpNode.destroy();
385
+ t._pool && t._pool.clear();
386
+ }
387
+
388
+ onEnable() {
389
+ // if (!CC_EDITOR)
390
+ this._registerEvent();
391
+ this._init();
392
+ // 处理重新显示后,有可能上一次的动画移除还未播放完毕,导致动画卡住的问题
393
+ if (this._aniDelRuning) {
394
+ this._aniDelRuning = false;
395
+ if (this._aniDelItem) {
396
+ if (this._aniDelBeforePos) {
397
+ this._aniDelItem.position = this._aniDelBeforePos;
398
+ delete this._aniDelBeforePos;
399
+ }
400
+ if (this._aniDelBeforeScale) {
401
+ this._aniDelItem.scale = this._aniDelBeforeScale;
402
+ delete this._aniDelBeforeScale;
403
+ }
404
+ delete this._aniDelItem;
405
+ }
406
+ if (this._aniDelCB) {
407
+ this._aniDelCB();
408
+ delete this._aniDelCB;
409
+ }
410
+ }
411
+ }
412
+
413
+ onDisable() {
414
+ // if (!CC_EDITOR)
415
+ this._unregisterEvent();
416
+ }
417
+ //注册事件
418
+ _registerEvent() {
419
+ let t: any = this;
420
+ t.node.on(cc.Node.EventType.TOUCH_START, t._onTouchStart, t, true);
421
+ t.node.on('touch-up', t._onTouchUp, t);
422
+ t.node.on(cc.Node.EventType.TOUCH_CANCEL, t._onTouchCancelled, t, true);
423
+ t.node.on('scroll-began', t._onScrollBegan, t, true);
424
+ t.node.on('scroll-ended', t._onScrollEnded, t, true);
425
+ t.node.on('scrolling', t._onScrolling, t, true);
426
+ t.node.on(cc.Node.EventType.SIZE_CHANGED, t._onSizeChanged, t);
427
+ }
428
+ //卸载事件
429
+ _unregisterEvent() {
430
+ let t: any = this;
431
+ t.node.off(cc.Node.EventType.TOUCH_START, t._onTouchStart, t, true);
432
+ t.node.off('touch-up', t._onTouchUp, t);
433
+ t.node.off(cc.Node.EventType.TOUCH_CANCEL, t._onTouchCancelled, t, true);
434
+ t.node.off('scroll-began', t._onScrollBegan, t, true);
435
+ t.node.off('scroll-ended', t._onScrollEnded, t, true);
436
+ t.node.off('scrolling', t._onScrolling, t, true);
437
+ t.node.off(cc.Node.EventType.SIZE_CHANGED, t._onSizeChanged, t);
438
+ }
439
+
440
+ //初始化各种..
441
+ _init() {
442
+ let t: any = this;
443
+ if (t._inited) return;
444
+
445
+ t._scrollView = t.node.getComponent(cc.ScrollView);
446
+
447
+ t.content = t._scrollView.content;
448
+ if (!t.content) {
449
+ FWLog.error(t.node.name + "'s cc.ScrollView unset content!");
450
+ return;
451
+ }
452
+
453
+ t._layout = t.content.getComponent(cc.Layout);
454
+
455
+ t._align = t._layout.type; //排列模式
456
+ t._resizeMode = t._layout.resizeMode; //自适应模式
457
+ t._startAxis = t._layout.startAxis;
458
+
459
+ t._topGap = t._layout.paddingTop; //顶边距
460
+ t._rightGap = t._layout.paddingRight; //右边距
461
+ t._bottomGap = t._layout.paddingBottom; //底边距
462
+ t._leftGap = t._layout.paddingLeft; //左边距
463
+
464
+ t._columnGap = t._layout.spacingX; //列距
465
+ t._lineGap = t._layout.spacingY; //行距
466
+
467
+ t._colLineNum; //列数或行数(非GRID模式则=1,表示单列或单行);
468
+
469
+ t._verticalDir = t._layout.verticalDirection; //垂直排列子节点的方向
470
+ t._horizontalDir = t._layout.horizontalDirection; //水平排列子节点的方向
471
+
472
+ t.setTemplateItem(
473
+ cc.instantiate(
474
+ t.templateType == FWSystemDefine.FWScrollViewTemplateType.PREFAB ? t.tmpPrefab : t.tmpNode,
475
+ ),
476
+ );
477
+
478
+ // 特定的滑动模式处理
479
+ if (
480
+ t._slideMode == FWSystemDefine.FWScrollViewSlideType.ADHERING ||
481
+ t._slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE
482
+ ) {
483
+ t._scrollView.inertia = false;
484
+ t._scrollView._onMouseWheel = function () {
485
+ return;
486
+ };
487
+ }
488
+ if (!t.virtual)
489
+ // lackCenter 仅支持 Virtual 模式
490
+ t.lackCenter = false;
491
+
492
+ t._lastDisplayData = []; //最后一次刷新的数据
493
+ t.displayData = []; //当前数据
494
+ t._pool = new cc.NodePool(); //这是个池子..
495
+ t._forceUpdate = false; //是否强制更新
496
+ t._updateCounter = 0; //当前分帧渲染帧数
497
+ t._updateDone = true; //分帧渲染是否完成
498
+
499
+ t.curPageNum = 0; //当前页数
500
+
501
+ if (t.cyclic || 0) {
502
+ t._scrollView._processAutoScrolling = this._processAutoScrolling.bind(t);
503
+ t._scrollView._startBounceBackIfNeeded = function () {
504
+ return false;
505
+ };
506
+ // t._scrollView._scrollChildren = function () {
507
+ // return false;
508
+ // }
509
+ }
510
+
511
+ switch (t._align) {
512
+ case cc.Layout.Type.HORIZONTAL: {
513
+ switch (t._horizontalDir) {
514
+ case cc.Layout.HorizontalDirection.LEFT_TO_RIGHT:
515
+ t._alignCalcType = 1;
516
+ break;
517
+ case cc.Layout.HorizontalDirection.RIGHT_TO_LEFT:
518
+ t._alignCalcType = 2;
519
+ break;
520
+ }
521
+ break;
522
+ }
523
+ case cc.Layout.Type.VERTICAL: {
524
+ switch (t._verticalDir) {
525
+ case cc.Layout.VerticalDirection.TOP_TO_BOTTOM:
526
+ t._alignCalcType = 3;
527
+ break;
528
+ case cc.Layout.VerticalDirection.BOTTOM_TO_TOP:
529
+ t._alignCalcType = 4;
530
+ break;
531
+ }
532
+ break;
533
+ }
534
+ case cc.Layout.Type.GRID: {
535
+ switch (t._startAxis) {
536
+ case cc.Layout.AxisDirection.HORIZONTAL:
537
+ switch (t._verticalDir) {
538
+ case cc.Layout.VerticalDirection.TOP_TO_BOTTOM:
539
+ t._alignCalcType = 3;
540
+ break;
541
+ case cc.Layout.VerticalDirection.BOTTOM_TO_TOP:
542
+ t._alignCalcType = 4;
543
+ break;
544
+ }
545
+ break;
546
+ case cc.Layout.AxisDirection.VERTICAL:
547
+ switch (t._horizontalDir) {
548
+ case cc.Layout.HorizontalDirection.LEFT_TO_RIGHT:
549
+ t._alignCalcType = 1;
550
+ break;
551
+ case cc.Layout.HorizontalDirection.RIGHT_TO_LEFT:
552
+ t._alignCalcType = 2;
553
+ break;
554
+ }
555
+ break;
556
+ }
557
+ break;
558
+ }
559
+ }
560
+ // 清空 content
561
+ // t.content.children.forEach((child: cc.Node) => {
562
+ // child.removeFromParent();
563
+ // if (child != t.tmpNode && child.isValid)
564
+ // child.destroy();
565
+ // });
566
+ t.content.removeAllChildren();
567
+ t._inited = true;
568
+ }
569
+ /**
570
+ * 为了实现循环列表,必须覆写cc.ScrollView的某些函数
571
+ * @param {Number} dt
572
+ */
573
+ _processAutoScrolling(dt: number) {
574
+ let brakingFactor: number = 1;
575
+ this._scrollView['_autoScrollAccumulatedTime'] += dt * (1 / brakingFactor);
576
+
577
+ let percentage: number = Math.min(
578
+ 1,
579
+ this._scrollView['_autoScrollAccumulatedTime'] / this._scrollView['_autoScrollTotalTime'],
580
+ );
581
+ if (this._scrollView['_autoScrollAttenuate']) {
582
+ let time: number = percentage - 1;
583
+ percentage = time * time * time * time * time + 1;
584
+ }
585
+
586
+ let newPosition: any = this._scrollView['_autoScrollStartPosition'].add(
587
+ this._scrollView['_autoScrollTargetDelta'].mul(percentage),
588
+ );
589
+ let EPSILON: number = this._scrollView['getScrollEndedEventTiming']();
590
+ let reachedEnd: boolean = Math.abs(percentage - 1) <= EPSILON;
591
+
592
+ let fireEvent: boolean =
593
+ Math.abs(percentage - 1) <= this._scrollView['getScrollEndedEventTiming']();
594
+ if (fireEvent && !this._scrollView['_isScrollEndedWithThresholdEventFired']) {
595
+ this._scrollView['_dispatchEvent']('scroll-ended-with-threshold');
596
+ this._scrollView['_isScrollEndedWithThresholdEventFired'] = true;
597
+ }
598
+
599
+ if (reachedEnd) {
600
+ this._scrollView['_autoScrolling'] = false;
601
+ }
602
+
603
+ let deltaMove: any = newPosition.sub(this._scrollView.getContentPosition());
604
+ this._scrollView['_moveContent'](this._scrollView['_clampDelta'](deltaMove), reachedEnd);
605
+ this._scrollView['_dispatchEvent']('scrolling');
606
+
607
+ // scollTo API controll move
608
+ if (!this._scrollView['_autoScrolling']) {
609
+ this._scrollView['_isBouncing'] = false;
610
+ this._scrollView['_scrolling'] = false;
611
+ this._scrollView['_dispatchEvent']('scroll-ended');
612
+ }
613
+ }
614
+ //设置模板Item
615
+ setTemplateItem(item: any) {
616
+ if (!item) return;
617
+ let t: any = this;
618
+ t._itemTmp = item;
619
+
620
+ if (t._resizeMode == cc.Layout.ResizeMode.CHILDREN) t._itemSize = t._layout.cellSize;
621
+ else t._itemSize = cc.size(item.width, item.height);
622
+
623
+ //获取ListItem,如果没有就取消选择模式
624
+ let com = item.getComponent(FWListItem);
625
+ let remove = false;
626
+ if (!com) remove = true;
627
+ // if (com) {
628
+ // if (!com._btnCom && !item.getComponent(cc.Button)) {
629
+ // remove = true;
630
+ // }
631
+ // }
632
+ if (remove) {
633
+ t.selectedMode = FWSystemDefine.FWScrollViewSelectedType.NONE;
634
+ }
635
+ com = item.getComponent(cc.Widget);
636
+ if (com && com.enabled) {
637
+ t._needUpdateWidget = true;
638
+ }
639
+ if (t.selectedMode == FWSystemDefine.FWScrollViewSelectedType.MULTIPLE) t.multSelected = [];
640
+
641
+ t._resetColumn();
642
+ }
643
+
644
+ _resetColumn() {
645
+ let t: any = this;
646
+ switch (t._align) {
647
+ case cc.Layout.Type.HORIZONTAL:
648
+ t._colLineNum = 1;
649
+ t._sizeType = false;
650
+ break;
651
+ case cc.Layout.Type.VERTICAL:
652
+ t._colLineNum = 1;
653
+ t._sizeType = true;
654
+ break;
655
+ case cc.Layout.Type.GRID:
656
+ switch (t._startAxis) {
657
+ case cc.Layout.AxisDirection.HORIZONTAL:
658
+ //计算列数
659
+ let trimW: number = t.content.width - t._leftGap - t._rightGap;
660
+ t._colLineNum = Math.floor((trimW + t._columnGap) / (t._itemSize.width + t._columnGap));
661
+ t._sizeType = true;
662
+ break;
663
+ case cc.Layout.AxisDirection.VERTICAL:
664
+ //计算行数
665
+ let trimH: number = t.content.height - t._topGap - t._bottomGap;
666
+ t._colLineNum = Math.floor((trimH + t._lineGap) / (t._itemSize.height + t._lineGap));
667
+ t._sizeType = false;
668
+ break;
669
+ }
670
+ break;
671
+ }
672
+ }
673
+
674
+ /**
675
+ * 检查是否初始化
676
+ * @param {Boolean} printLog 是否打印错误信息
677
+ * @returns
678
+ */
679
+ checkInited(printLog: boolean = true) {
680
+ if (!this._inited) {
681
+ if (printLog) FWLog.error('List initialization not completed!');
682
+ return false;
683
+ }
684
+ return true;
685
+ }
686
+ //禁用 Layout 组件,自行计算 Content Size
687
+ _resizeContent() {
688
+ let t: any = this;
689
+ let result: number;
690
+ t._resetColumn();
691
+ switch (t._align) {
692
+ case cc.Layout.Type.HORIZONTAL: {
693
+ if (t._customSize) {
694
+ let fixed: any = t._getFixedSize(null);
695
+ result =
696
+ t._leftGap +
697
+ fixed.val +
698
+ t._itemSize.width * (t._numItems - fixed.count) +
699
+ t._columnGap * (t._numItems - 1) +
700
+ t._rightGap;
701
+ } else {
702
+ result =
703
+ t._leftGap +
704
+ t._itemSize.width * t._numItems +
705
+ t._columnGap * (t._numItems - 1) +
706
+ t._rightGap;
707
+ }
708
+ break;
709
+ }
710
+ case cc.Layout.Type.VERTICAL: {
711
+ if (t._customSize) {
712
+ let fixed: any = t._getFixedSize(null);
713
+ result =
714
+ t._topGap +
715
+ fixed.val +
716
+ t._itemSize.height * (t._numItems - fixed.count) +
717
+ t._lineGap * (t._numItems - 1) +
718
+ t._bottomGap;
719
+ } else {
720
+ result =
721
+ t._topGap +
722
+ t._itemSize.height * t._numItems +
723
+ t._lineGap * (t._numItems - 1) +
724
+ t._bottomGap;
725
+ }
726
+ break;
727
+ }
728
+ case cc.Layout.Type.GRID: {
729
+ //网格模式不支持居中
730
+ if (t.lackCenter) t.lackCenter = false;
731
+ switch (t._startAxis) {
732
+ case cc.Layout.AxisDirection.HORIZONTAL:
733
+ let lineNum: number = Math.ceil(t._numItems / t._colLineNum);
734
+ result =
735
+ t._topGap + t._itemSize.height * lineNum + t._lineGap * (lineNum - 1) + t._bottomGap;
736
+ break;
737
+ case cc.Layout.AxisDirection.VERTICAL:
738
+ let colNum: number = Math.ceil(t._numItems / t._colLineNum);
739
+ result =
740
+ t._leftGap + t._itemSize.width * colNum + t._columnGap * (colNum - 1) + t._rightGap;
741
+ break;
742
+ }
743
+ break;
744
+ }
745
+ }
746
+
747
+ let layout: cc.Layout = t.content.getComponent(cc.Layout);
748
+ if (layout) layout.enabled = false;
749
+
750
+ t._allItemSize = result;
751
+ t._allItemSizeNoEdge =
752
+ t._allItemSize - (t._sizeType ? t._topGap + t._bottomGap : t._leftGap + t._rightGap);
753
+
754
+ if (t.cyclic) {
755
+ let totalSize: number = t._sizeType ? t.node.height : t.node.width;
756
+
757
+ t._cyclicPos1 = 0;
758
+ totalSize -= t._cyclicPos1;
759
+ t._cyclicNum = Math.ceil(totalSize / t._allItemSizeNoEdge) + 1;
760
+ let spacing: number = t._sizeType ? t._lineGap : t._columnGap;
761
+ t._cyclicPos2 = t._cyclicPos1 + t._allItemSizeNoEdge + spacing;
762
+ t._cyclicAllItemSize =
763
+ t._allItemSize + t._allItemSizeNoEdge * (t._cyclicNum - 1) + spacing * (t._cyclicNum - 1);
764
+ t._cycilcAllItemSizeNoEdge = t._allItemSizeNoEdge * t._cyclicNum;
765
+ t._cycilcAllItemSizeNoEdge += spacing * (t._cyclicNum - 1);
766
+ // cc.log('_cyclicNum ->', t._cyclicNum, t._allItemSizeNoEdge, t._allItemSize, t._cyclicPos1, t._cyclicPos2);
767
+ }
768
+
769
+ t._lack = !t.cyclic && t._allItemSize < (t._sizeType ? t.node.height : t.node.width);
770
+ let slideOffset: number = (!t._lack || !t.lackCenter) && t.lackSlide ? 0 : 0.1;
771
+
772
+ let targetWH: number = t._lack
773
+ ? (t._sizeType ? t.node.height : t.node.width) - slideOffset
774
+ : t.cyclic
775
+ ? t._cyclicAllItemSize
776
+ : t._allItemSize;
777
+ if (targetWH < 0) targetWH = 0;
778
+
779
+ if (t._sizeType) {
780
+ t.content.height = targetWH;
781
+ } else {
782
+ t.content.width = targetWH;
783
+ }
784
+
785
+ // cc.log('_resizeContent() numItems =', t._numItems, ',content =', t.content);
786
+ }
787
+
788
+ //滚动进行时...
789
+ _onScrolling(ev: cc.Event = null) {
790
+ if (this.frameCount == null) this.frameCount = this._updateRate;
791
+ if (!this._forceUpdate && ev && ev.type != 'scroll-ended' && this.frameCount > 0) {
792
+ this.frameCount--;
793
+ return;
794
+ } else this.frameCount = this._updateRate;
795
+
796
+ if (this._aniDelRuning) return;
797
+
798
+ //循环列表处理
799
+ if (this.cyclic) {
800
+ let scrollPos: any = this.content.getPosition();
801
+ scrollPos = this._sizeType ? scrollPos.y : scrollPos.x;
802
+
803
+ let addVal = this._allItemSizeNoEdge + (this._sizeType ? this._lineGap : this._columnGap);
804
+ let add: any = this._sizeType ? cc.v2(0, addVal) : cc.v2(addVal, 0);
805
+
806
+ switch (this._alignCalcType) {
807
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
808
+ if (scrollPos > -this._cyclicPos1) {
809
+ this.content.x = -this._cyclicPos2;
810
+ if (this._scrollView.isAutoScrolling()) {
811
+ this._scrollView['_autoScrollStartPosition'] =
812
+ this._scrollView['_autoScrollStartPosition'].sub(add);
813
+ }
814
+ // if (this._beganPos) {
815
+ // this._beganPos += add;
816
+ // }
817
+ } else if (scrollPos < -this._cyclicPos2) {
818
+ this.content.x = -this._cyclicPos1;
819
+ if (this._scrollView.isAutoScrolling()) {
820
+ this._scrollView['_autoScrollStartPosition'] =
821
+ this._scrollView['_autoScrollStartPosition'].add(add);
822
+ }
823
+ // if (this._beganPos) {
824
+ // this._beganPos -= add;
825
+ // }
826
+ }
827
+ break;
828
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
829
+ if (scrollPos < this._cyclicPos1) {
830
+ this.content.x = this._cyclicPos2;
831
+ if (this._scrollView.isAutoScrolling()) {
832
+ this._scrollView['_autoScrollStartPosition'] =
833
+ this._scrollView['_autoScrollStartPosition'].add(add);
834
+ }
835
+ } else if (scrollPos > this._cyclicPos2) {
836
+ this.content.x = this._cyclicPos1;
837
+ if (this._scrollView.isAutoScrolling()) {
838
+ this._scrollView['_autoScrollStartPosition'] =
839
+ this._scrollView['_autoScrollStartPosition'].sub(add);
840
+ }
841
+ }
842
+ break;
843
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
844
+ if (scrollPos < this._cyclicPos1) {
845
+ this.content.y = this._cyclicPos2;
846
+ if (this._scrollView.isAutoScrolling()) {
847
+ this._scrollView['_autoScrollStartPosition'] =
848
+ this._scrollView['_autoScrollStartPosition'].add(add);
849
+ }
850
+ } else if (scrollPos > this._cyclicPos2) {
851
+ this.content.y = this._cyclicPos1;
852
+ if (this._scrollView.isAutoScrolling()) {
853
+ this._scrollView['_autoScrollStartPosition'] =
854
+ this._scrollView['_autoScrollStartPosition'].sub(add);
855
+ }
856
+ }
857
+ break;
858
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
859
+ if (scrollPos > -this._cyclicPos1) {
860
+ this.content.y = -this._cyclicPos2;
861
+ if (this._scrollView.isAutoScrolling()) {
862
+ this._scrollView['_autoScrollStartPosition'] =
863
+ this._scrollView['_autoScrollStartPosition'].sub(add);
864
+ }
865
+ } else if (scrollPos < -this._cyclicPos2) {
866
+ this.content.y = -this._cyclicPos1;
867
+ if (this._scrollView.isAutoScrolling()) {
868
+ this._scrollView['_autoScrollStartPosition'] =
869
+ this._scrollView['_autoScrollStartPosition'].add(add);
870
+ }
871
+ }
872
+ break;
873
+ }
874
+ }
875
+
876
+ this._calcViewPos();
877
+
878
+ let vTop: number, vRight: number, vBottom: number, vLeft: number;
879
+ if (this._sizeType) {
880
+ vTop = this.viewTop;
881
+ vBottom = this.viewBottom;
882
+ } else {
883
+ vRight = this.viewRight;
884
+ vLeft = this.viewLeft;
885
+ }
886
+
887
+ if (this._virtual) {
888
+ this.displayData = [];
889
+ let itemPos: any;
890
+
891
+ let curId: number = 0;
892
+ let endId: number = this._numItems - 1;
893
+
894
+ if (this._customSize) {
895
+ let breakFor: boolean = false;
896
+ //如果该item的位置在可视区域内,就推入displayData
897
+ for (; curId <= endId && !breakFor; curId++) {
898
+ itemPos = this._calcItemPos(curId);
899
+ switch (this._align) {
900
+ case cc.Layout.Type.HORIZONTAL:
901
+ if (itemPos.right >= vLeft && itemPos.left <= vRight) {
902
+ this.displayData.push(itemPos);
903
+ } else if (curId != 0 && this.displayData.length > 0) {
904
+ breakFor = true;
905
+ }
906
+ break;
907
+ case cc.Layout.Type.VERTICAL:
908
+ if (itemPos.bottom <= vTop && itemPos.top >= vBottom) {
909
+ this.displayData.push(itemPos);
910
+ } else if (curId != 0 && this.displayData.length > 0) {
911
+ breakFor = true;
912
+ }
913
+ break;
914
+ case cc.Layout.Type.GRID:
915
+ switch (this._startAxis) {
916
+ case cc.Layout.AxisDirection.HORIZONTAL:
917
+ if (itemPos.bottom <= vTop && itemPos.top >= vBottom) {
918
+ this.displayData.push(itemPos);
919
+ } else if (curId != 0 && this.displayData.length > 0) {
920
+ breakFor = true;
921
+ }
922
+ break;
923
+ case cc.Layout.AxisDirection.VERTICAL:
924
+ if (itemPos.right >= vLeft && itemPos.left <= vRight) {
925
+ this.displayData.push(itemPos);
926
+ } else if (curId != 0 && this.displayData.length > 0) {
927
+ breakFor = true;
928
+ }
929
+ break;
930
+ }
931
+ break;
932
+ }
933
+ }
934
+ } else {
935
+ let ww: number = this._itemSize.width + this._columnGap;
936
+ let hh: number = this._itemSize.height + this._lineGap;
937
+ switch (this._alignCalcType) {
938
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
939
+ curId = (vLeft - this._leftGap) / ww;
940
+ endId = (vRight - this._leftGap) / ww;
941
+ break;
942
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
943
+ curId = (-vRight - this._rightGap) / ww;
944
+ endId = (-vLeft - this._rightGap) / ww;
945
+ break;
946
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
947
+ curId = (-vTop - this._topGap) / hh;
948
+ endId = (-vBottom - this._topGap) / hh;
949
+ break;
950
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
951
+ curId = (vBottom - this._bottomGap) / hh;
952
+ endId = (vTop - this._bottomGap) / hh;
953
+ break;
954
+ }
955
+ curId = Math.floor(curId) * this._colLineNum;
956
+ endId = Math.ceil(endId) * this._colLineNum;
957
+ endId--;
958
+ if (curId < 0) curId = 0;
959
+ if (endId >= this._numItems) endId = this._numItems - 1;
960
+ for (; curId <= endId; curId++) {
961
+ this.displayData.push(this._calcItemPos(curId));
962
+ }
963
+ }
964
+ this._delRedundantItem();
965
+ if (this.displayData.length <= 0 || !this._numItems) {
966
+ //if none, delete all.
967
+ this._lastDisplayData = [];
968
+ return;
969
+ }
970
+ this.firstListId = this.displayData[0].id;
971
+ this.displayItemNum = this.displayData.length;
972
+
973
+ let len: number = this._lastDisplayData.length;
974
+
975
+ let haveDataChange: boolean = this.displayItemNum != len;
976
+ if (haveDataChange) {
977
+ // 如果是逐帧渲染,需要排序
978
+ if (this.frameByFrameRenderNum > 0) {
979
+ this._lastDisplayData.sort((a, b) => {
980
+ return a - b;
981
+ });
982
+ }
983
+ // 因List的显示数据是有序的,所以只需要判断数组长度是否相等,以及头、尾两个元素是否相等即可。
984
+ haveDataChange =
985
+ this.firstListId != this._lastDisplayData[0] ||
986
+ this.displayData[this.displayItemNum - 1].id != this._lastDisplayData[len - 1];
987
+ }
988
+
989
+ if (this._forceUpdate || haveDataChange) {
990
+ //如果是强制更新
991
+ if (this.frameByFrameRenderNum > 0) {
992
+ // if (this._updateDone) {
993
+ // this._lastDisplayData = [];
994
+ //逐帧渲染
995
+ if (this._numItems > 0) {
996
+ if (!this._updateDone) {
997
+ this._doneAfterUpdate = true;
998
+ } else {
999
+ this._updateCounter = 0;
1000
+ }
1001
+ this._updateDone = false;
1002
+ } else {
1003
+ this._updateCounter = 0;
1004
+ this._updateDone = true;
1005
+ }
1006
+ // }
1007
+ } else {
1008
+ //直接渲染
1009
+ this._lastDisplayData = [];
1010
+ // cc.log('List Display Data II::', this.displayData);
1011
+ for (let c = 0; c < this.displayItemNum; c++) {
1012
+ this._createOrUpdateItem(this.displayData[c]);
1013
+ }
1014
+ this._forceUpdate = false;
1015
+ }
1016
+ }
1017
+ this._calcNearestItem();
1018
+ }
1019
+ }
1020
+ //计算可视范围
1021
+ _calcViewPos() {
1022
+ let scrollPos: any = this.content.getPosition();
1023
+ switch (this._alignCalcType) {
1024
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
1025
+ this.elasticLeft = scrollPos.x > 0 ? scrollPos.x : 0;
1026
+ this.viewLeft = (scrollPos.x < 0 ? -scrollPos.x : 0) - this.elasticLeft;
1027
+ this.viewRight = this.viewLeft + this.node.width;
1028
+ this.elasticRight =
1029
+ this.viewRight > this.content.width ? Math.abs(this.viewRight - this.content.width) : 0;
1030
+ this.viewRight += this.elasticRight;
1031
+ // cc.log(this.elasticLeft, this.elasticRight, this.viewLeft, this.viewRight);
1032
+ break;
1033
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
1034
+ this.elasticRight = scrollPos.x < 0 ? -scrollPos.x : 0;
1035
+ this.viewRight = (scrollPos.x > 0 ? -scrollPos.x : 0) + this.elasticRight;
1036
+ this.viewLeft = this.viewRight - this.node.width;
1037
+ this.elasticLeft =
1038
+ this.viewLeft < -this.content.width ? Math.abs(this.viewLeft + this.content.width) : 0;
1039
+ this.viewLeft -= this.elasticLeft;
1040
+ // cc.log(this.elasticLeft, this.elasticRight, this.viewLeft, this.viewRight);
1041
+ break;
1042
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
1043
+ this.elasticTop = scrollPos.y < 0 ? Math.abs(scrollPos.y) : 0;
1044
+ this.viewTop = (scrollPos.y > 0 ? -scrollPos.y : 0) + this.elasticTop;
1045
+ this.viewBottom = this.viewTop - this.node.height;
1046
+ this.elasticBottom =
1047
+ this.viewBottom < -this.content.height
1048
+ ? Math.abs(this.viewBottom + this.content.height)
1049
+ : 0;
1050
+ this.viewBottom += this.elasticBottom;
1051
+ // cc.log(this.elasticTop, this.elasticBottom, this.viewTop, this.viewBottom);
1052
+ break;
1053
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
1054
+ this.elasticBottom = scrollPos.y > 0 ? Math.abs(scrollPos.y) : 0;
1055
+ this.viewBottom = (scrollPos.y < 0 ? -scrollPos.y : 0) - this.elasticBottom;
1056
+ this.viewTop = this.viewBottom + this.node.height;
1057
+ this.elasticTop =
1058
+ this.viewTop > this.content.height ? Math.abs(this.viewTop - this.content.height) : 0;
1059
+ this.viewTop -= this.elasticTop;
1060
+ // cc.log(this.elasticTop, this.elasticBottom, this.viewTop, this.viewBottom);
1061
+ break;
1062
+ }
1063
+ }
1064
+ //计算位置 根据id
1065
+ _calcItemPos(id: number) {
1066
+ let width: number,
1067
+ height: number,
1068
+ top: number,
1069
+ bottom: number,
1070
+ left: number,
1071
+ right: number,
1072
+ itemX: number,
1073
+ itemY: number;
1074
+ switch (this._align) {
1075
+ case cc.Layout.Type.HORIZONTAL:
1076
+ switch (this._horizontalDir) {
1077
+ case cc.Layout.HorizontalDirection.LEFT_TO_RIGHT: {
1078
+ if (this._customSize) {
1079
+ let fixed: any = this._getFixedSize(id);
1080
+ left =
1081
+ this._leftGap +
1082
+ (this._itemSize.width + this._columnGap) * (id - fixed.count) +
1083
+ (fixed.val + this._columnGap * fixed.count);
1084
+ let cs: number = this._customSize[id];
1085
+ width = cs > 0 ? cs : this._itemSize.width;
1086
+ } else {
1087
+ left = this._leftGap + (this._itemSize.width + this._columnGap) * id;
1088
+ width = this._itemSize.width;
1089
+ }
1090
+ if (this.lackCenter) {
1091
+ left -= this._leftGap;
1092
+ let offset: number = this.content.width / 2 - this._allItemSizeNoEdge / 2;
1093
+ left += offset;
1094
+ }
1095
+ right = left + width;
1096
+ return {
1097
+ id: id,
1098
+ left: left,
1099
+ right: right,
1100
+ x: left + this._itemTmp.anchorX * width,
1101
+ y: this._itemTmp.y,
1102
+ };
1103
+ }
1104
+ case cc.Layout.HorizontalDirection.RIGHT_TO_LEFT: {
1105
+ if (this._customSize) {
1106
+ let fixed: any = this._getFixedSize(id);
1107
+ right =
1108
+ -this._rightGap -
1109
+ (this._itemSize.width + this._columnGap) * (id - fixed.count) -
1110
+ (fixed.val + this._columnGap * fixed.count);
1111
+ let cs: number = this._customSize[id];
1112
+ width = cs > 0 ? cs : this._itemSize.width;
1113
+ } else {
1114
+ right = -this._rightGap - (this._itemSize.width + this._columnGap) * id;
1115
+ width = this._itemSize.width;
1116
+ }
1117
+ if (this.lackCenter) {
1118
+ right += this._rightGap;
1119
+ let offset: number = this.content.width / 2 - this._allItemSizeNoEdge / 2;
1120
+ right -= offset;
1121
+ }
1122
+ left = right - width;
1123
+ return {
1124
+ id: id,
1125
+ right: right,
1126
+ left: left,
1127
+ x: left + this._itemTmp.anchorX * width,
1128
+ y: this._itemTmp.y,
1129
+ };
1130
+ }
1131
+ }
1132
+ break;
1133
+ case cc.Layout.Type.VERTICAL: {
1134
+ switch (this._verticalDir) {
1135
+ case cc.Layout.VerticalDirection.TOP_TO_BOTTOM: {
1136
+ if (this._customSize) {
1137
+ let fixed: any = this._getFixedSize(id);
1138
+ top =
1139
+ -this._topGap -
1140
+ (this._itemSize.height + this._lineGap) * (id - fixed.count) -
1141
+ (fixed.val + this._lineGap * fixed.count);
1142
+ let cs: number = this._customSize[id];
1143
+ height = cs > 0 ? cs : this._itemSize.height;
1144
+ } else {
1145
+ top = -this._topGap - (this._itemSize.height + this._lineGap) * id;
1146
+ height = this._itemSize.height;
1147
+ }
1148
+ if (this.lackCenter) {
1149
+ top += this._topGap;
1150
+ let offset: number = this.content.height / 2 - this._allItemSizeNoEdge / 2;
1151
+ top -= offset;
1152
+ }
1153
+ bottom = top - height;
1154
+ return {
1155
+ id: id,
1156
+ top: top,
1157
+ bottom: bottom,
1158
+ x: this._itemTmp.x,
1159
+ y: bottom + this._itemTmp.anchorY * height,
1160
+ };
1161
+ }
1162
+ case cc.Layout.VerticalDirection.BOTTOM_TO_TOP: {
1163
+ if (this._customSize) {
1164
+ let fixed: any = this._getFixedSize(id);
1165
+ bottom =
1166
+ this._bottomGap +
1167
+ (this._itemSize.height + this._lineGap) * (id - fixed.count) +
1168
+ (fixed.val + this._lineGap * fixed.count);
1169
+ let cs: number = this._customSize[id];
1170
+ height = cs > 0 ? cs : this._itemSize.height;
1171
+ } else {
1172
+ bottom = this._bottomGap + (this._itemSize.height + this._lineGap) * id;
1173
+ height = this._itemSize.height;
1174
+ }
1175
+ if (this.lackCenter) {
1176
+ bottom -= this._bottomGap;
1177
+ let offset: number = this.content.height / 2 - this._allItemSizeNoEdge / 2;
1178
+ bottom += offset;
1179
+ }
1180
+ top = bottom + height;
1181
+ return {
1182
+ id: id,
1183
+ top: top,
1184
+ bottom: bottom,
1185
+ x: this._itemTmp.x,
1186
+ y: bottom + this._itemTmp.anchorY * height,
1187
+ };
1188
+ break;
1189
+ }
1190
+ }
1191
+ }
1192
+ case cc.Layout.Type.GRID: {
1193
+ let colLine: number = Math.floor(id / this._colLineNum);
1194
+ switch (this._startAxis) {
1195
+ case cc.Layout.AxisDirection.HORIZONTAL: {
1196
+ switch (this._verticalDir) {
1197
+ case cc.Layout.VerticalDirection.TOP_TO_BOTTOM: {
1198
+ top = -this._topGap - (this._itemSize.height + this._lineGap) * colLine;
1199
+ bottom = top - this._itemSize.height;
1200
+ itemY = bottom + this._itemTmp.anchorY * this._itemSize.height;
1201
+ break;
1202
+ }
1203
+ case cc.Layout.VerticalDirection.BOTTOM_TO_TOP: {
1204
+ bottom = this._bottomGap + (this._itemSize.height + this._lineGap) * colLine;
1205
+ top = bottom + this._itemSize.height;
1206
+ itemY = bottom + this._itemTmp.anchorY * this._itemSize.height;
1207
+ break;
1208
+ }
1209
+ }
1210
+ itemX =
1211
+ this._leftGap + (id % this._colLineNum) * (this._itemSize.width + this._columnGap);
1212
+ switch (this._horizontalDir) {
1213
+ case cc.Layout.HorizontalDirection.LEFT_TO_RIGHT: {
1214
+ itemX += this._itemTmp.anchorX * this._itemSize.width;
1215
+ itemX -= this.content.anchorX * this.content.width;
1216
+ break;
1217
+ }
1218
+ case cc.Layout.HorizontalDirection.RIGHT_TO_LEFT: {
1219
+ itemX += (1 - this._itemTmp.anchorX) * this._itemSize.width;
1220
+ itemX -= (1 - this.content.anchorX) * this.content.width;
1221
+ itemX *= -1;
1222
+ break;
1223
+ }
1224
+ }
1225
+ return {
1226
+ id: id,
1227
+ top: top,
1228
+ bottom: bottom,
1229
+ x: itemX,
1230
+ y: itemY,
1231
+ };
1232
+ }
1233
+ case cc.Layout.AxisDirection.VERTICAL: {
1234
+ switch (this._horizontalDir) {
1235
+ case cc.Layout.HorizontalDirection.LEFT_TO_RIGHT: {
1236
+ left = this._leftGap + (this._itemSize.width + this._columnGap) * colLine;
1237
+ right = left + this._itemSize.width;
1238
+ itemX = left + this._itemTmp.anchorX * this._itemSize.width;
1239
+ itemX -= this.content.anchorX * this.content.width;
1240
+ break;
1241
+ }
1242
+ case cc.Layout.HorizontalDirection.RIGHT_TO_LEFT: {
1243
+ right = -this._rightGap - (this._itemSize.width + this._columnGap) * colLine;
1244
+ left = right - this._itemSize.width;
1245
+ itemX = left + this._itemTmp.anchorX * this._itemSize.width;
1246
+ itemX += (1 - this.content.anchorX) * this.content.width;
1247
+ break;
1248
+ }
1249
+ }
1250
+ itemY =
1251
+ -this._topGap - (id % this._colLineNum) * (this._itemSize.height + this._lineGap);
1252
+ switch (this._verticalDir) {
1253
+ case cc.Layout.VerticalDirection.TOP_TO_BOTTOM: {
1254
+ itemY -= (1 - this._itemTmp.anchorY) * this._itemSize.height;
1255
+ itemY += (1 - this.content.anchorY) * this.content.height;
1256
+ break;
1257
+ }
1258
+ case cc.Layout.VerticalDirection.BOTTOM_TO_TOP: {
1259
+ itemY -= this._itemTmp.anchorY * this._itemSize.height;
1260
+ itemY += this.content.anchorY * this.content.height;
1261
+ itemY *= -1;
1262
+ break;
1263
+ }
1264
+ }
1265
+ return {
1266
+ id: id,
1267
+ left: left,
1268
+ right: right,
1269
+ x: itemX,
1270
+ y: itemY,
1271
+ };
1272
+ }
1273
+ }
1274
+ break;
1275
+ }
1276
+ }
1277
+ }
1278
+ //计算已存在的Item的位置
1279
+ _calcExistItemPos(id: number) {
1280
+ let item: any = this.getItemByListId(id);
1281
+ if (!item) return null;
1282
+ let data: any = {
1283
+ id: id,
1284
+ x: item.x,
1285
+ y: item.y,
1286
+ };
1287
+ if (this._sizeType) {
1288
+ data.top = item.y + item.height * (1 - item.anchorY);
1289
+ data.bottom = item.y - item.height * item.anchorY;
1290
+ } else {
1291
+ data.left = item.x - item.width * item.anchorX;
1292
+ data.right = item.x + item.width * (1 - item.anchorX);
1293
+ }
1294
+ return data;
1295
+ }
1296
+ //获取Item位置
1297
+ getItemPos(id: number) {
1298
+ if (this._virtual) return this._calcItemPos(id);
1299
+ else {
1300
+ if (this.frameByFrameRenderNum) return this._calcItemPos(id);
1301
+ else return this._calcExistItemPos(id);
1302
+ }
1303
+ }
1304
+ //获取固定尺寸
1305
+ _getFixedSize(listId: number) {
1306
+ if (!this._customSize) return null;
1307
+ if (listId == null) listId = this._numItems;
1308
+ let fixed: number = 0;
1309
+ let count: number = 0;
1310
+ for (let id in this._customSize) {
1311
+ if (parseInt(id) < listId) {
1312
+ fixed += this._customSize[id];
1313
+ count++;
1314
+ }
1315
+ }
1316
+ return {
1317
+ val: fixed,
1318
+ count: count,
1319
+ };
1320
+ }
1321
+ //滚动结束时..
1322
+ _onScrollBegan() {
1323
+ this._beganPos = this._sizeType ? this.viewTop : this.viewLeft;
1324
+ }
1325
+ //滚动结束时..
1326
+ _onScrollEnded() {
1327
+ let t: any = this;
1328
+ t.curScrollIsTouch = false;
1329
+ if (t.scrollToListId != null) {
1330
+ let item: any = t.getItemByListId(t.scrollToListId);
1331
+ t.scrollToListId = null;
1332
+ if (item) {
1333
+ cc.tween(item).to(0.1, { scale: 1.06 }).to(0.1, { scale: 1 }).start();
1334
+ }
1335
+ }
1336
+ t._onScrolling();
1337
+
1338
+ if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.ADHERING && !t.adhering) {
1339
+ //cc.log(t.adhering, t._scrollView.isAutoScrolling(), t._scrollView.isScrolling());
1340
+ t.adhere();
1341
+ } else if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE) {
1342
+ if (t._beganPos != null && t.curScrollIsTouch) {
1343
+ this._pageAdhere();
1344
+ } else {
1345
+ t.adhere();
1346
+ }
1347
+ }
1348
+ }
1349
+ // 触摸时
1350
+ _onTouchStart(ev, captureListeners) {
1351
+ if ((this._scrollView['hasNestedViewGroup'] as any)(ev, captureListeners)) return;
1352
+ this.curScrollIsTouch = true;
1353
+ let isMe = ev.eventPhase === cc.Event.AT_TARGET && ev.target === this.node;
1354
+ if (!isMe) {
1355
+ let itemNode: any = ev.target;
1356
+ while (itemNode._listId == null && itemNode.parent) itemNode = itemNode.parent;
1357
+ this._scrollItem = itemNode._listId != null ? itemNode : ev.target;
1358
+ }
1359
+ }
1360
+ //触摸抬起时..
1361
+ _onTouchUp() {
1362
+ let t: any = this;
1363
+ t._scrollPos = null;
1364
+ if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.ADHERING) {
1365
+ if (this.adhering) this._adheringBarrier = true;
1366
+ t.adhere();
1367
+ } else if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE) {
1368
+ if (t._beganPos != null) {
1369
+ this._pageAdhere();
1370
+ } else {
1371
+ t.adhere();
1372
+ }
1373
+ }
1374
+ this._scrollItem = null;
1375
+ }
1376
+
1377
+ _onTouchCancelled(ev, captureListeners) {
1378
+ let t = this;
1379
+ if ((this._scrollView['hasNestedViewGroup'] as any)(ev, captureListeners) || ev.simulate)
1380
+ return;
1381
+
1382
+ t._scrollPos = null;
1383
+ if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.ADHERING) {
1384
+ if (t.adhering) t._adheringBarrier = true;
1385
+ t.adhere();
1386
+ } else if (t._slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE) {
1387
+ if (t._beganPos != null) {
1388
+ t._pageAdhere();
1389
+ } else {
1390
+ t.adhere();
1391
+ }
1392
+ }
1393
+ this._scrollItem = null;
1394
+ }
1395
+ //当尺寸改变
1396
+ _onSizeChanged() {
1397
+ if (this.checkInited(false)) this._onScrolling();
1398
+ }
1399
+ //当Item自适应
1400
+ _onItemAdaptive(item) {
1401
+ // if (this.checkInited(false)) {
1402
+ if (
1403
+ (!this._sizeType && item.width != this._itemSize.width) ||
1404
+ (this._sizeType && item.height != this._itemSize.height)
1405
+ ) {
1406
+ if (!this._customSize) this._customSize = {};
1407
+ let val = this._sizeType ? item.height : item.width;
1408
+ if (this._customSize[item._listId] != val) {
1409
+ this._customSize[item._listId] = val;
1410
+ this._resizeContent();
1411
+ this.updateAll();
1412
+ if (this._scrollToListId != null) {
1413
+ this._scrollPos = null;
1414
+ this.unschedule(this._scrollToSo);
1415
+ this.scrollTo(
1416
+ this._scrollToListId,
1417
+ Math.max(0, this._scrollToEndTime - new Date().getTime() / 1000),
1418
+ );
1419
+ }
1420
+ }
1421
+ }
1422
+ // }
1423
+ }
1424
+ //PAGE粘附
1425
+ _pageAdhere() {
1426
+ let t = this;
1427
+ if (
1428
+ !t.cyclic &&
1429
+ (t.elasticTop > 0 || t.elasticRight > 0 || t.elasticBottom > 0 || t.elasticLeft > 0)
1430
+ )
1431
+ return;
1432
+ let curPos = t._sizeType ? t.viewTop : t.viewLeft;
1433
+ let dis = (t._sizeType ? t.node.height : t.node.width) * t.pageDistance;
1434
+ let canSkip = Math.abs(t._beganPos - curPos) > dis;
1435
+ if (canSkip) {
1436
+ let timeInSecond = 0.5;
1437
+ switch (t._alignCalcType) {
1438
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
1439
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
1440
+ if (t._beganPos > curPos) {
1441
+ t.prePage(timeInSecond);
1442
+ // cc.log('_pageAdhere PPPPPPPPPPPPPPP');
1443
+ } else {
1444
+ t.nextPage(timeInSecond);
1445
+ // cc.log('_pageAdhere NNNNNNNNNNNNNNN');
1446
+ }
1447
+ break;
1448
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
1449
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
1450
+ if (t._beganPos < curPos) {
1451
+ t.prePage(timeInSecond);
1452
+ } else {
1453
+ t.nextPage(timeInSecond);
1454
+ }
1455
+ break;
1456
+ }
1457
+ } else if (
1458
+ t.elasticTop <= 0 &&
1459
+ t.elasticRight <= 0 &&
1460
+ t.elasticBottom <= 0 &&
1461
+ t.elasticLeft <= 0
1462
+ ) {
1463
+ t.adhere();
1464
+ }
1465
+ t._beganPos = null;
1466
+ }
1467
+ //粘附
1468
+ adhere() {
1469
+ let t: any = this;
1470
+ if (!t.checkInited()) return;
1471
+ if (t.elasticTop > 0 || t.elasticRight > 0 || t.elasticBottom > 0 || t.elasticLeft > 0) return;
1472
+ t.adhering = true;
1473
+ t._calcNearestItem();
1474
+ let offset: number =
1475
+ (t._sizeType ? t._topGap : t._leftGap) / (t._sizeType ? t.node.height : t.node.width);
1476
+ let timeInSecond: number = 0.7;
1477
+ t.scrollTo(t.nearestListId, timeInSecond, offset);
1478
+ }
1479
+ //Update..
1480
+ update() {
1481
+ if (this.frameByFrameRenderNum <= 0 || this._updateDone) return;
1482
+ // cc.log(this.displayData.length, this._updateCounter, this.displayData[this._updateCounter]);
1483
+ if (this._virtual) {
1484
+ let len: number =
1485
+ this._updateCounter + this.frameByFrameRenderNum > this.displayItemNum
1486
+ ? this.displayItemNum
1487
+ : this._updateCounter + this.frameByFrameRenderNum;
1488
+ for (let n: number = this._updateCounter; n < len; n++) {
1489
+ let data: any = this.displayData[n];
1490
+ if (data) {
1491
+ this._createOrUpdateItem(data);
1492
+ }
1493
+ }
1494
+
1495
+ if (this._updateCounter >= this.displayItemNum - 1) {
1496
+ //最后一个
1497
+ if (this._doneAfterUpdate) {
1498
+ this._updateCounter = 0;
1499
+ this._updateDone = false;
1500
+ // if (!this._scrollView.isScrolling())
1501
+ this._doneAfterUpdate = false;
1502
+ } else {
1503
+ this._updateDone = true;
1504
+ this._delRedundantItem();
1505
+ this._forceUpdate = false;
1506
+ this._calcNearestItem();
1507
+ if (this.slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE)
1508
+ this.curPageNum = this.nearestListId;
1509
+ }
1510
+ } else {
1511
+ this._updateCounter += this.frameByFrameRenderNum;
1512
+ }
1513
+ } else {
1514
+ if (this._updateCounter < this._numItems) {
1515
+ let len: number =
1516
+ this._updateCounter + this.frameByFrameRenderNum > this._numItems
1517
+ ? this._numItems
1518
+ : this._updateCounter + this.frameByFrameRenderNum;
1519
+ for (let n: number = this._updateCounter; n < len; n++) {
1520
+ this._createOrUpdateItem2(n);
1521
+ }
1522
+ this._updateCounter += this.frameByFrameRenderNum;
1523
+ } else {
1524
+ this._updateDone = true;
1525
+ this._calcNearestItem();
1526
+ if (this.slideMode == FWSystemDefine.FWScrollViewSlideType.PAGE)
1527
+ this.curPageNum = this.nearestListId;
1528
+ }
1529
+ }
1530
+ }
1531
+ /**
1532
+ * 创建或更新Item(虚拟列表用)
1533
+ * @param {Object} data 数据
1534
+ */
1535
+ _createOrUpdateItem(data: any) {
1536
+ let item: any = this.getItemByListId(data.id);
1537
+ if (!item) {
1538
+ //如果不存在
1539
+ let canGet: boolean = this._pool.size() > 0;
1540
+ if (canGet) {
1541
+ item = this._pool.get();
1542
+ // cc.log('从池中取出:: 旧id =', item['_listId'], ',新id =', data.id, item);
1543
+ } else {
1544
+ item = cc.instantiate(this._itemTmp);
1545
+ // cc.log('新建::', data.id, item);
1546
+ }
1547
+ if (!canGet || !cc.isValid(item)) {
1548
+ item = cc.instantiate(this._itemTmp);
1549
+ canGet = false;
1550
+ }
1551
+ if (item._listId != data.id) {
1552
+ item._listId = data.id;
1553
+ item.setContentSize(this._itemSize);
1554
+ }
1555
+ item.setPosition(cc.v2(data.x, data.y));
1556
+ this._resetItemSize(item);
1557
+ this.content.addChild(item);
1558
+ if (canGet && this._needUpdateWidget && this.isUpdateWidget) {
1559
+ let widget: cc.Widget = item.getComponent(cc.Widget);
1560
+ if (widget) widget.updateAlignment();
1561
+ }
1562
+ item.setSiblingIndex(this.content.childrenCount - 1);
1563
+
1564
+ let listItem: FWListItem = item.getComponent(FWListItem);
1565
+ item['listItem'] = listItem;
1566
+ if (listItem) {
1567
+ listItem.listId = data.id;
1568
+ listItem.list = this;
1569
+ listItem._registerEvent();
1570
+ }
1571
+ this.onRender?.(item, data.id % this._actualNumItems);
1572
+ } else if (this._forceUpdate && this.onRender) {
1573
+ //强制更新
1574
+ item.setPosition(cc.v2(data.x, data.y));
1575
+ this._resetItemSize(item);
1576
+ this.onRender?.(item, data.id % this._actualNumItems);
1577
+ }
1578
+ this._resetItemSize(item);
1579
+
1580
+ if (this._lastDisplayData.indexOf(data.id) < 0) {
1581
+ this._lastDisplayData.push(data.id);
1582
+ }
1583
+ }
1584
+ //创建或更新Item(非虚拟列表用)
1585
+ _createOrUpdateItem2(listId: number) {
1586
+ let item: any = this.content.children[listId];
1587
+ let listItem: FWListItem;
1588
+ if (!item) {
1589
+ //如果不存在
1590
+ item = cc.instantiate(this._itemTmp);
1591
+ item._listId = listId;
1592
+ this.content.addChild(item);
1593
+ listItem = item.getComponent(FWListItem);
1594
+ item['listItem'] = listItem;
1595
+ if (listItem) {
1596
+ listItem.listId = listId;
1597
+ listItem.list = this;
1598
+ listItem._registerEvent();
1599
+ }
1600
+ this.onRender?.(item, listId % this._actualNumItems);
1601
+ } else if (this._forceUpdate && this.onRender) {
1602
+ //强制更新
1603
+ item._listId = listId;
1604
+ if (listItem) listItem.listId = listId;
1605
+
1606
+ this.onRender?.(item, listId % this._actualNumItems);
1607
+ }
1608
+
1609
+ if (this._lastDisplayData.indexOf(listId) < 0) {
1610
+ this._lastDisplayData.push(listId);
1611
+ }
1612
+ }
1613
+
1614
+ //仅虚拟列表用
1615
+ _resetItemSize(item: any) {
1616
+ return;
1617
+ let size: number;
1618
+ if (this._customSize && this._customSize[item._listId]) {
1619
+ size = this._customSize[item._listId];
1620
+ } else {
1621
+ if (this._colLineNum > 1) item.setContentSize(this._itemSize);
1622
+ else size = this._sizeType ? this._itemSize.height : this._itemSize.width;
1623
+ }
1624
+ if (size) {
1625
+ if (this._sizeType) item.height = size;
1626
+ else item.width = size;
1627
+ }
1628
+ }
1629
+ /**
1630
+ * 更新Item位置
1631
+ * @param {Number||Node} listIdOrItem
1632
+ */
1633
+ _updateItemPos(listIdOrItem: any) {
1634
+ let item: any = isNaN(listIdOrItem) ? listIdOrItem : this.getItemByListId(listIdOrItem);
1635
+ let pos: any = this.getItemPos(item._listId);
1636
+ item.setPosition(pos.x, pos.y);
1637
+ }
1638
+ /**
1639
+ * 设置多选
1640
+ * @param {Array} args 可以是单个listId,也可是个listId数组
1641
+ * @param {Boolean} bool 值,如果为null的话,则直接用args覆盖
1642
+ */
1643
+ setMultSelected(args: any, bool: boolean) {
1644
+ let t: any = this;
1645
+ if (!t.checkInited()) return;
1646
+ if (!Array.isArray(args)) {
1647
+ args = [args];
1648
+ }
1649
+ if (bool == null) {
1650
+ t.multSelected = args;
1651
+ } else {
1652
+ let listId: number, sub: number;
1653
+ if (bool) {
1654
+ for (let n: number = args.length - 1; n >= 0; n--) {
1655
+ listId = args[n];
1656
+ sub = t.multSelected.indexOf(listId);
1657
+ if (sub < 0) {
1658
+ t.multSelected.push(listId);
1659
+ }
1660
+ }
1661
+ } else {
1662
+ for (let n: number = args.length - 1; n >= 0; n--) {
1663
+ listId = args[n];
1664
+ sub = t.multSelected.indexOf(listId);
1665
+ if (sub >= 0) {
1666
+ t.multSelected.splice(sub, 1);
1667
+ }
1668
+ }
1669
+ }
1670
+ }
1671
+ t._forceUpdate = true;
1672
+ t._onScrolling();
1673
+ }
1674
+ /**
1675
+ * 获取多选数据
1676
+ * @returns
1677
+ */
1678
+ getMultSelected() {
1679
+ return this.multSelected;
1680
+ }
1681
+ /**
1682
+ * 多选是否有选择
1683
+ * @param {number} listId 索引
1684
+ * @returns
1685
+ */
1686
+ hasMultSelected(listId: number) {
1687
+ return this.multSelected && this.multSelected.indexOf(listId) >= 0;
1688
+ }
1689
+ /**
1690
+ * 更新指定的Item
1691
+ * @param {Array} args 单个listId,或者数组
1692
+ * @returns
1693
+ */
1694
+ updateItem(args: any) {
1695
+ if (!this.checkInited()) return;
1696
+ if (!Array.isArray(args)) {
1697
+ args = [args];
1698
+ }
1699
+ for (let n: number = 0, len: number = args.length; n < len; n++) {
1700
+ let listId: number = args[n];
1701
+ let item: any = this.getItemByListId(listId);
1702
+ if (item) this.onRender?.(item, listId % this._actualNumItems);
1703
+ }
1704
+ }
1705
+ /**
1706
+ * 更新全部
1707
+ */
1708
+ updateAll() {
1709
+ if (!this.checkInited()) return;
1710
+ this.numItems = this.numItems;
1711
+ }
1712
+ /**
1713
+ * 根据ListID获取Item
1714
+ * @param {Number} listId
1715
+ * @returns
1716
+ */
1717
+ getItemByListId(listId: number) {
1718
+ if (this.content) {
1719
+ for (let n: number = this.content.childrenCount - 1; n >= 0; n--) {
1720
+ let item: any = this.content.children[n];
1721
+ if (item._listId == listId) return item;
1722
+ }
1723
+ }
1724
+ }
1725
+ /**
1726
+ * 获取在显示区域外的Item
1727
+ * @returns
1728
+ */
1729
+ _getOutsideItem() {
1730
+ let item: any;
1731
+ let result: any[] = [];
1732
+ for (let n: number = this.content.childrenCount - 1; n >= 0; n--) {
1733
+ item = this.content.children[n];
1734
+ if (!this.displayData.find((d) => d.id == item._listId)) {
1735
+ result.push(item);
1736
+ }
1737
+ }
1738
+ return result;
1739
+ }
1740
+ //删除显示区域以外的Item
1741
+ _delRedundantItem() {
1742
+ if (this._virtual) {
1743
+ let arr: any[] = this._getOutsideItem();
1744
+ for (let n: number = arr.length - 1; n >= 0; n--) {
1745
+ let item: any = arr[n];
1746
+ if (this._scrollItem && item._listId == this._scrollItem._listId) continue;
1747
+ item.isCached = true;
1748
+ this._pool.put(item);
1749
+ for (let m: number = this._lastDisplayData.length - 1; m >= 0; m--) {
1750
+ if (this._lastDisplayData[m] == item._listId) {
1751
+ this._lastDisplayData.splice(m, 1);
1752
+ break;
1753
+ }
1754
+ }
1755
+ }
1756
+ // cc.log('存入::', str, ' pool.length =', this._pool.length);
1757
+ } else {
1758
+ while (this.content.childrenCount > this._numItems) {
1759
+ this._delSingleItem(this.content.children[this.content.childrenCount - 1]);
1760
+ }
1761
+ }
1762
+ }
1763
+ //删除单个Item
1764
+ _delSingleItem(item: any) {
1765
+ // cc.log('DEL::', item['_listId'], item);
1766
+ item.removeFromParent();
1767
+ if (item.destroy) item.destroy();
1768
+ item = null;
1769
+ }
1770
+ /**
1771
+ * 动效删除Item(此方法只适用于虚拟列表,即_virtual=true)
1772
+ * 一定要在回调函数里重新设置新的numItems进行刷新,毕竟本List是靠数据驱动的。
1773
+ */
1774
+ aniDelItem(listId: number, callFunc: Function, aniType: number) {
1775
+ let t: any = this;
1776
+
1777
+ if (!t.checkInited() || t.cyclic || !t._virtual)
1778
+ return FWLog.error('This function is not allowed to be called!');
1779
+
1780
+ if (!callFunc)
1781
+ return FWLog.error(
1782
+ 'CallFunc are not allowed to be NULL, You need to delete the corresponding index in the data array in the CallFunc!',
1783
+ );
1784
+
1785
+ if (t._aniDelRuning) return cc.warn('Please wait for the current deletion to finish!');
1786
+
1787
+ let item: any = t.getItemByListId(listId);
1788
+ let listItem: FWListItem;
1789
+ if (!item) {
1790
+ callFunc(listId);
1791
+ return;
1792
+ } else {
1793
+ listItem = item.getComponent(FWListItem);
1794
+ }
1795
+ t._aniDelRuning = true;
1796
+ t._aniDelCB = callFunc;
1797
+ t._aniDelItem = item;
1798
+ t._aniDelBeforePos = item.position;
1799
+ t._aniDelBeforeScale = item.scale;
1800
+ let curLastId: number = t.displayData[t.displayData.length - 1].id;
1801
+ listItem.showAni(
1802
+ aniType,
1803
+ () => {
1804
+ //判断有没有下一个,如果有的话,创建粗来
1805
+ let newId: number;
1806
+ if (curLastId < t._numItems - 2) {
1807
+ newId = curLastId + 1;
1808
+ }
1809
+ if (newId != null) {
1810
+ let newData: any = t._calcItemPos(newId);
1811
+ t.displayData.push(newData);
1812
+ if (t._virtual) t._createOrUpdateItem(newData);
1813
+ else t._createOrUpdateItem2(newId);
1814
+ } else t._numItems--;
1815
+ if (t.selectedMode == FWSystemDefine.FWScrollViewSelectedType.SINGLE) {
1816
+ } else if (
1817
+ t.selectedMode == FWSystemDefine.FWScrollViewSelectedType.MULTIPLE &&
1818
+ t.multSelected.length
1819
+ ) {
1820
+ let sub: number = t.multSelected.indexOf(listId);
1821
+ if (sub >= 0) {
1822
+ t.multSelected.splice(sub, 1);
1823
+ }
1824
+ //多选的数据,在其后的全部减一
1825
+ for (let n: number = t.multSelected.length - 1; n >= 0; n--) {
1826
+ let id: number = t.multSelected[n];
1827
+ if (id >= listId) t.multSelected[n]--;
1828
+ }
1829
+ }
1830
+ if (t._customSize) {
1831
+ if (t._customSize[listId]) delete t._customSize[listId];
1832
+ let newCustomSize: any = {};
1833
+ let size: number;
1834
+ for (let id in t._customSize) {
1835
+ size = t._customSize[id];
1836
+ let idNumber: number = parseInt(id);
1837
+ newCustomSize[idNumber - (idNumber >= listId ? 1 : 0)] = size;
1838
+ }
1839
+ t._customSize = newCustomSize;
1840
+ }
1841
+ //后面的Item向前怼的动效
1842
+ let sec: number = 0.2333;
1843
+ let tween: cc.Tween, haveCB: boolean;
1844
+ for (let n: number = newId != null ? newId : curLastId; n >= listId + 1; n--) {
1845
+ item = t.getItemByListId(n);
1846
+ if (item) {
1847
+ let posData: any = t._calcItemPos(n - 1);
1848
+ tween = cc.tween(item).to(sec, { position: cc.v2(posData.x, posData.y) });
1849
+ if (n <= listId + 1) {
1850
+ haveCB = true;
1851
+ tween.call(() => {
1852
+ t._aniDelRuning = false;
1853
+ callFunc(listId);
1854
+ delete t._aniDelCB;
1855
+ });
1856
+ }
1857
+ tween.start();
1858
+ }
1859
+ }
1860
+ if (!haveCB) {
1861
+ t._aniDelRuning = false;
1862
+ callFunc(listId);
1863
+ t._aniDelCB = null;
1864
+ }
1865
+ },
1866
+ true,
1867
+ );
1868
+ }
1869
+ /**
1870
+ * 滚动到..
1871
+ * @param {Number} listId 索引(如果<0,则滚到首个Item位置,如果>=_numItems,则滚到最末Item位置)
1872
+ * @param {Number} timeInSecond 时间
1873
+ * @param {Number} offset 索引目标位置偏移,0-1
1874
+ * @param {Boolean} overStress 滚动后是否强调该Item(这只是个实验功能)
1875
+ */
1876
+ scrollTo(
1877
+ listId: number,
1878
+ timeInSecond: number = 0.5,
1879
+ offset: number = null,
1880
+ overStress: boolean = false,
1881
+ ) {
1882
+ let t = this;
1883
+ if (!t.checkInited(false)) return;
1884
+ t._scrollView.stopAutoScroll();
1885
+ if (timeInSecond == null)
1886
+ //默认0.5
1887
+ timeInSecond = 0.5;
1888
+ else if (timeInSecond < 0) timeInSecond = 0;
1889
+ if (listId < 0) listId = 0;
1890
+ else if (listId >= t._numItems) listId = t._numItems - 1;
1891
+ // 以防设置了numItems之后layout的尺寸还未更新
1892
+ if (!t._virtual && t._layout && t._layout.enabled) t._layout.updateLayout();
1893
+
1894
+ let pos = t.getItemPos(listId);
1895
+ if (!pos) {
1896
+ return CC_DEV && FWLog.error('pos is null', listId);
1897
+ }
1898
+ let targetX: number, targetY: number;
1899
+
1900
+ switch (t._alignCalcType) {
1901
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
1902
+ targetX = pos.left;
1903
+ if (offset != null) targetX -= t.node.width * offset;
1904
+ else targetX -= t._leftGap;
1905
+ pos = cc.v2(targetX, 0);
1906
+ break;
1907
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
1908
+ targetX = pos.right - t.node.width;
1909
+ if (offset != null) targetX += t.node.width * offset;
1910
+ else targetX += t._rightGap;
1911
+ pos = cc.v2(targetX + t.content.width, 0);
1912
+ break;
1913
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
1914
+ targetY = pos.top;
1915
+ if (offset != null) targetY += t.node.height * offset;
1916
+ else targetY += t._topGap;
1917
+ pos = cc.v2(0, -targetY);
1918
+ break;
1919
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
1920
+ targetY = pos.bottom + t.node.height;
1921
+ if (offset != null) targetY -= t.node.height * offset;
1922
+ else targetY -= t._bottomGap;
1923
+ pos = cc.v2(0, -targetY + t.content.height);
1924
+ break;
1925
+ }
1926
+ let viewPos: any = t.content.getPosition();
1927
+ viewPos = Math.abs(t._sizeType ? viewPos.y : viewPos.x);
1928
+
1929
+ let comparePos = t._sizeType ? pos.y : pos.x;
1930
+ let runScroll = Math.abs((t._scrollPos != null ? t._scrollPos : viewPos) - comparePos) > 0.5;
1931
+ // cc.log(runScroll, t._scrollPos, viewPos, comparePos)
1932
+
1933
+ t._scrollView.stopAutoScroll();
1934
+ if (runScroll) {
1935
+ t._scrollView.scrollToOffset(pos, timeInSecond);
1936
+ t._scrollToListId = listId;
1937
+ t._scrollToEndTime = new Date().getTime() / 1000 + timeInSecond;
1938
+ // cc.log(listId, t.content.width, t.content.getPosition(), pos);
1939
+ t._scrollToSo = t.scheduleOnce(() => {
1940
+ if (!t._adheringBarrier) {
1941
+ t.adhering = t._adheringBarrier = false;
1942
+ }
1943
+ t._scrollPos = t._scrollToListId = t._scrollToEndTime = t._scrollToSo = null;
1944
+ //cc.log('2222222222', t._adheringBarrier)
1945
+ if (overStress) {
1946
+ // t.scrollToListId = listId;
1947
+ let item = t.getItemByListId(listId);
1948
+ if (item) {
1949
+ cc.tween(item).to(0.1, { scale: 1.05 }).to(0.1, { scale: 1 }).start();
1950
+ }
1951
+ }
1952
+ }, timeInSecond + 0.1);
1953
+
1954
+ if (timeInSecond <= 0) {
1955
+ t._onScrolling();
1956
+ }
1957
+ }
1958
+ }
1959
+ /**
1960
+ * 计算当前滚动窗最近的Item
1961
+ */
1962
+ _calcNearestItem() {
1963
+ let t: any = this;
1964
+ t.nearestListId = null;
1965
+ let data: any, center: number;
1966
+
1967
+ if (t._virtual) t._calcViewPos();
1968
+
1969
+ let vTop: number, vRight: number, vBottom: number, vLeft: number;
1970
+ vTop = t.viewTop;
1971
+ vRight = t.viewRight;
1972
+ vBottom = t.viewBottom;
1973
+ vLeft = t.viewLeft;
1974
+
1975
+ let breakFor: boolean = false;
1976
+ for (let n = 0; n < t.content.childrenCount && !breakFor; n += t._colLineNum) {
1977
+ data = t._virtual ? t.displayData[n] : t._calcExistItemPos(n);
1978
+ if (data) {
1979
+ center = t._sizeType
1980
+ ? (data.top + data.bottom) / 2
1981
+ : (center = (data.left + data.right) / 2);
1982
+ switch (t._alignCalcType) {
1983
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
1984
+ if (data.right >= vLeft) {
1985
+ t.nearestListId = data.id;
1986
+ if (vLeft > center) t.nearestListId += t._colLineNum;
1987
+ breakFor = true;
1988
+ }
1989
+ break;
1990
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
1991
+ if (data.left <= vRight) {
1992
+ t.nearestListId = data.id;
1993
+ if (vRight < center) t.nearestListId += t._colLineNum;
1994
+ breakFor = true;
1995
+ }
1996
+ break;
1997
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
1998
+ if (data.bottom <= vTop) {
1999
+ t.nearestListId = data.id;
2000
+ if (vTop < center) t.nearestListId += t._colLineNum;
2001
+ breakFor = true;
2002
+ }
2003
+ break;
2004
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
2005
+ if (data.top >= vBottom) {
2006
+ t.nearestListId = data.id;
2007
+ if (vBottom > center) t.nearestListId += t._colLineNum;
2008
+ breakFor = true;
2009
+ }
2010
+ break;
2011
+ }
2012
+ }
2013
+ }
2014
+ //判断最后一个Item。。。(哎,这些判断真心恶心,判断了前面的还要判断最后一个。。。一开始呢,就只有一个布局(单列布局),那时候代码才三百行,后来就想着完善啊,艹..这坑真深,现在这行数都一千五了= =||)
2015
+ data = t._virtual ? t.displayData[t.displayItemNum - 1] : t._calcExistItemPos(t._numItems - 1);
2016
+ if (data && data.id == t._numItems - 1) {
2017
+ center = t._sizeType ? (data.top + data.bottom) / 2 : (center = (data.left + data.right) / 2);
2018
+ switch (t._alignCalcType) {
2019
+ case 1: //单行HORIZONTAL(LEFT_TO_RIGHT)、网格VERTICAL(LEFT_TO_RIGHT)
2020
+ if (vRight > center) t.nearestListId = data.id;
2021
+ break;
2022
+ case 2: //单行HORIZONTAL(RIGHT_TO_LEFT)、网格VERTICAL(RIGHT_TO_LEFT)
2023
+ if (vLeft < center) t.nearestListId = data.id;
2024
+ break;
2025
+ case 3: //单列VERTICAL(TOP_TO_BOTTOM)、网格HORIZONTAL(TOP_TO_BOTTOM)
2026
+ if (vBottom < center) t.nearestListId = data.id;
2027
+ break;
2028
+ case 4: //单列VERTICAL(BOTTOM_TO_TOP)、网格HORIZONTAL(BOTTOM_TO_TOP)
2029
+ if (vTop > center) t.nearestListId = data.id;
2030
+ break;
2031
+ }
2032
+ }
2033
+ // cc.log('t.nearestListId =', t.nearestListId);
2034
+ }
2035
+ //上一页
2036
+ prePage(timeInSecond: number = 0.5) {
2037
+ // cc.log('👈');
2038
+ if (!this.checkInited()) return;
2039
+ this.skipPage(this.curPageNum - 1, timeInSecond);
2040
+ }
2041
+ //下一页
2042
+ nextPage(timeInSecond: number = 0.5) {
2043
+ // cc.log('👉');
2044
+ if (!this.checkInited()) return;
2045
+ this.skipPage(this.curPageNum + 1, timeInSecond);
2046
+ }
2047
+ //跳转到第几页
2048
+ skipPage(pageNum: number, timeInSecond: number) {
2049
+ let t: any = this;
2050
+ if (!t.checkInited()) return;
2051
+ if (t._slideMode != FWSystemDefine.FWScrollViewSlideType.PAGE)
2052
+ return FWLog.error('This function is not allowed to be called, Must SlideMode = PAGE!');
2053
+ if (pageNum < 0 || pageNum >= t._numItems) return;
2054
+ if (t.curPageNum == pageNum) return;
2055
+ // cc.log(pageNum);
2056
+ t.curPageNum = pageNum;
2057
+ t.onPageChange?.(null, pageNum);
2058
+ t.scrollTo(pageNum, timeInSecond);
2059
+ }
2060
+ //计算 CustomSize(这个函数还是保留吧,某些罕见的情况的确还是需要手动计算customSize的)
2061
+ calcCustomSize(numItems: number) {
2062
+ let t: any = this;
2063
+ if (!t.checkInited()) return;
2064
+ if (!t._itemTmp) return FWLog.error('Unset template item!');
2065
+ if (!t.renderEvent) return FWLog.error('Unset Render-Event!');
2066
+ t._customSize = {};
2067
+ let temp: any = cc.instantiate(t._itemTmp);
2068
+ t.content.addChild(temp);
2069
+ for (let n: number = 0; n < numItems; n++) {
2070
+ cc.Component.EventHandler.emitEvents([t.renderEvent], temp, n);
2071
+ if (temp.height != t._itemSize.height || temp.width != t._itemSize.width) {
2072
+ t._customSize[n] = t._sizeType ? temp.height : temp.width;
2073
+ }
2074
+ }
2075
+ if (!Object.keys(t._customSize).length) t._customSize = null;
2076
+ temp.removeFromParent();
2077
+ if (temp.destroy) temp.destroy();
2078
+ return t._customSize;
2079
+ }
2080
+ }