987bdad7-582e-4bcf-a639-c8db02544c05.js 88 KB

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