ListViewAdpater.js 6.7 KB

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