ListViewAdpater.js 6.9 KB

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