ListViewAdapter.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. class ListViewAdapter {
  2. constructor(scrollView) {
  3. this.scrollView = scrollView;
  4. this.content = scrollView.content;
  5. this.scriptItems = [];
  6. this.dataList = [];
  7. // this.initialize();
  8. this.updateTimer = 0;
  9. this.updateInterval = 0.1;
  10. this.lastContentPosY = 0; // use this variable to detect if we are scrolling up or down
  11. this.spawnCount = 16;
  12. this.itemHeight = 0;
  13. this.bufferZone = 500;
  14. this.spacing = 10;
  15. this.scriptName = '';
  16. this.fuckingItem = null;
  17. }
  18. initialize(itemTemplate) {
  19. console.log(this.scriptName);
  20. let actualCount = this.dataList.length < this.spawnCount ? this.dataList.length : this.spawnCount;
  21. // let actualCount = this.dataList.length;
  22. if (this.itemHeight > 0) {
  23. this.bufferZone = this.scrollView.node.height / 2 + this.content.height / 2;
  24. this.content.height = (this.itemHeight + this.spacing) * this.dataList.length;
  25. }
  26. this.scriptItems = [];
  27. this.content.removeAllChildren();
  28. for (let i = 0; i < actualCount; i++) { // spawn items, we only need to do this once
  29. let item = cc.instantiate(itemTemplate);
  30. if (this.itemHeight === 0) {
  31. this.itemHeight = item.height; // get total content height
  32. this.bufferZone = this.scrollView.node.height / 2 + this.content.height / 2;
  33. this.content.height = (this.itemHeight + this.spacing) * this.dataList.length;
  34. }
  35. this.content.addChild(item);
  36. item.setPosition(0, -item.height * (0.5 + i) - this.spacing * (i + 1));
  37. let itemScript = item.getComponent(this.scriptName);
  38. // itemScript.setListViewAdapter(this);
  39. itemScript.updateItem(this.dataList[i], i);
  40. this.scriptItems.push(itemScript);
  41. }
  42. }
  43. getPositionInView(item) { // get item position in scrollview's node space
  44. let worldPos = item.parent.convertToWorldSpaceAR(item.position);
  45. let viewPos = this.scrollView.node.convertToNodeSpaceAR(worldPos);
  46. return viewPos;
  47. }
  48. update(dt) {
  49. this.updateTimer += dt;
  50. if (this.updateTimer < this.updateInterval) return; // we don't need to do the math every frame
  51. this.updateTimer = 0;
  52. let buffer = this.bufferZone;
  53. let isDown = this.content.y < this.lastContentPosY; // scrolling direction
  54. let offset = (this.itemHeight + this.spacing) * this.scriptItems.length;
  55. for (let i = 0; i < this.scriptItems.length; ++i) {
  56. let viewPos = this.getPositionInView(this.scriptItems[i].node);
  57. if (isDown) {
  58. // if away from buffer zone and not reaching top of content
  59. if (viewPos.y < -buffer && this.scriptItems[i].node.y + offset < 0) {
  60. this.scriptItems[i].node.y = this.scriptItems[i].node.y + offset;
  61. let itemScript = this.scriptItems[i];
  62. let itemId = itemScript._itemId - this.scriptItems.length;
  63. itemScript.updateItem(this.dataList[itemId], itemId);
  64. }
  65. } else {
  66. // if away from buffer zone and not reaching bottom of content
  67. if (viewPos.y > buffer && this.scriptItems[i].node.y - offset > -this.content.height) {
  68. this.scriptItems[i].node.y = this.scriptItems[i].node.y - offset;
  69. let itemScript = this.scriptItems[i];
  70. let itemId = itemScript._itemId + scriptItems.length;
  71. itemScript.updateItem(this.dataList[itemId], itemId);
  72. if (itemId === (this.dataList.length - 1)) {
  73. if (this.loadMore != undefined) {
  74. this.loadMore();
  75. }
  76. }
  77. }
  78. }
  79. }
  80. // update lastContentPosY
  81. this.lastContentPosY = this.content.y;
  82. }
  83. updateItems(dataList, itemPrefab, scriptName) {
  84. this.scriptName = scriptName;
  85. this.itemTemplate = itemPrefab;
  86. this.dataList = dataList;
  87. this.initialize(itemPrefab);
  88. }
  89. addData(newdataList) {
  90. this.dataList = this.dataList.concat(newdataList);
  91. this.content.height = (this.itemHeight + this.spacing) * this.dataList.length; // get total content height
  92. }
  93. setLoadMoreCallBack(loadMore) {
  94. this.loadMore = loadMore;
  95. }
  96. playRemoveItemAnimation(itemScript, animCallback) {
  97. this.dataList.splice(itemScript._itemId, 1);
  98. this.content.height = (this.itemHeight + this.spacing) * this.dataList.length; // get total content height
  99. let sequ = cc.sequence(cc.moveBy(0.2, -750, 0), animCallback);
  100. itemScript.node.runAction(sequ);
  101. }
  102. updateItemsAndDataList(itemScript) {
  103. let index = itemScript._itemId;
  104. let scriptItems = this.scriptItems;
  105. if (this.dataList.length >= scriptItems.length) {
  106. itemScript.scheduleOnce(() => {
  107. itemScript.node.x = 0;
  108. }, 0.2);
  109. for (let i = 0; i < scriptItems.length; ++i) {
  110. let itemNode = scriptItems[i].node;
  111. let script = scriptItems[i];
  112. let itemId = script._itemId;
  113. if (itemId < this.dataList.length) {
  114. if (script._itemId > index) {
  115. let finish = cc.callFunc(() => {
  116. itemNode.y = itemNode.y - (this.itemHeight + this.spacing);
  117. script.updateItem(this.dataList[itemId], itemId);
  118. }, this);
  119. let s = cc.sequence(cc.moveBy(0.2, 0, (this.itemHeight + this.spacing)), finish);
  120. itemNode.runAction(s);
  121. } else {
  122. itemScript.scheduleOnce(() => {
  123. script.updateItem(this.dataList[itemId], itemId);
  124. }, 0.2);
  125. }
  126. }
  127. }
  128. } else {
  129. for (let i = 0; i < scriptItems.length; ++i) {
  130. let itemId = scriptItems[i]._itemId;
  131. if (itemId === itemScript._itemId) {
  132. this.scriptItems.splice(i, 1);
  133. }
  134. }
  135. for (let i = 0; i < scriptItems.length; ++i) {
  136. let itemNode = scriptItems[i].node;
  137. let script = scriptItems[i];
  138. if (script._itemId > index) {
  139. let newId = script._itemId - 1;
  140. itemNode.runAction(cc.moveBy(0.2, 0, (this.itemHeight + this.spacing)));
  141. script.updateItem(this.dataList[newId], newId);
  142. }
  143. }
  144. itemScript.node.destroy();
  145. }
  146. }
  147. removeItem(itemScript) {
  148. let finish = cc.callFunc(() => {
  149. this.updateItemsAndDataList(itemScript);
  150. });
  151. this.playRemoveItemAnimation(itemScript, finish);
  152. }
  153. onDestroy() {
  154. this.scriptItems = [];
  155. this.content.removeAllChildren();
  156. }
  157. }
  158. module.exports = ListViewAdapter;