ListViewAdapter.js 7.1 KB

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