ListViewCtrl.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. cc.Class({
  2. extends: cc.Component,
  3. properties: {
  4. itemTemplate: { // item template to instantiate other items
  5. default: null,
  6. type: cc.Node
  7. },
  8. scrollView: {
  9. default: null,
  10. type: cc.ScrollView
  11. },
  12. spawnCount: 0, // how many items we actually spawn
  13. totalCount: 0, // how many items we need for the whole list
  14. spacing: 0, // space between each item
  15. bufferZone: 0, // when item is away from bufferZone, we relocate it
  16. lblScrollEvent: cc.Label,
  17. btnAddItem: cc.Button,
  18. btnRemoveItem: cc.Button,
  19. btnJumpToPosition: cc.Button,
  20. lblJumpPosition: cc.Label,
  21. lblTotalItems: cc.Label,
  22. },
  23. // use this for initialization
  24. onLoad: function () {
  25. this.content = this.scrollView.content;
  26. this.items = []; // array to store spawned items
  27. this.initialize();
  28. this.updateTimer = 0;
  29. this.updateInterval = 0.2;
  30. this.lastContentPosY = 0; // use this variable to detect if we are scrolling up or down
  31. },
  32. initialize: function () {
  33. this.content.height = this.totalCount * (this.itemTemplate.height + this.spacing) + this.spacing; // get total content height
  34. for (let i = 0; i < this.spawnCount; ++i) { // spawn items, we only need to do this once
  35. let item = cc.instantiate(this.itemTemplate);
  36. this.content.addChild(item);
  37. item.setPosition(0, -item.height * (0.5 + i) - this.spacing * (i + 1));
  38. item.getComponent('Item').initItem(i, i);
  39. this.items.push(item);
  40. }
  41. },
  42. getPositionInView: function (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: function(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 items = this.items;
  52. let buffer = this.bufferZone;
  53. let isDown = this.scrollView.content.y < this.lastContentPosY; // scrolling direction
  54. let offset = (this.itemTemplate.height + this.spacing) * items.length;
  55. for (let i = 0; i < items.length; ++i) {
  56. let viewPos = this.getPositionInView(items[i]);
  57. if (isDown) {
  58. // if away from buffer zone and not reaching top of content
  59. if (viewPos.y < -buffer && items[i].y + offset < 0) {
  60. items[i].y = items[i].y + offset;
  61. let item = items[i].getComponent('Item');
  62. let itemId = item.itemID - items.length; // update item id
  63. item.updateItem(itemId);
  64. }
  65. } else {
  66. // if away from buffer zone and not reaching bottom of content
  67. if (viewPos.y > buffer && items[i].y - offset > -this.content.height) {
  68. items[i].y = items[i].y - offset;
  69. let item = items[i].getComponent('Item');
  70. let itemId = item.itemID + items.length;
  71. item.updateItem(itemId);
  72. }
  73. }
  74. }
  75. // update lastContentPosY
  76. this.lastContentPosY = this.scrollView.content.y;
  77. this.lblTotalItems.textKey = "Total Items: " + this.totalCount;
  78. },
  79. scrollEvent: function(sender, event) {
  80. switch(event) {
  81. case 0:
  82. this.lblScrollEvent.string = "Scroll to Top";
  83. break;
  84. case 1:
  85. this.lblScrollEvent.string = "Scroll to Bottom";
  86. break;
  87. case 2:
  88. this.lblScrollEvent.string = "Scroll to Left";
  89. break;
  90. case 3:
  91. this.lblScrollEvent.string = "Scroll to Right";
  92. break;
  93. case 4:
  94. this.lblScrollEvent.string = "Scrolling";
  95. break;
  96. case 5:
  97. this.lblScrollEvent.string = "Bounce Top";
  98. break;
  99. case 6:
  100. this.lblScrollEvent.string = "Bounce bottom";
  101. break;
  102. case 7:
  103. this.lblScrollEvent.string = "Bounce left";
  104. break;
  105. case 8:
  106. this.lblScrollEvent.string = "Bounce right";
  107. break;
  108. case 9:
  109. this.lblScrollEvent.string = "Auto scroll ended";
  110. break;
  111. }
  112. },
  113. addItem: function() {
  114. this.content.height = (this.totalCount + 1) * (this.itemTemplate.height + this.spacing) + this.spacing; // get total content height
  115. this.totalCount = this.totalCount + 1;
  116. },
  117. removeItem: function() {
  118. if (this.totalCount - 1 < 30) {
  119. cc.error("can't remove item less than 30!");
  120. return;
  121. }
  122. this.content.height = (this.totalCount - 1) * (this.itemTemplate.height + this.spacing) + this.spacing; // get total content height
  123. this.totalCount = this.totalCount - 1;
  124. this.moveBottomItemToTop();
  125. },
  126. moveBottomItemToTop () {
  127. let offset = (this.itemTemplate.height + this.spacing) * this.items.length;
  128. let length = this.items.length;
  129. let item = this.getItemAtBottom();
  130. // whether need to move to top
  131. if (item.y + offset < 0) {
  132. item.y = item.y + offset;
  133. let itemComp = item.getComponent('Item');
  134. let itemId = itemComp.itemID - length;
  135. itemComp.updateItem(itemId);
  136. }
  137. },
  138. getItemAtBottom () {
  139. let item = this.items[0];
  140. for (let i = 1; i < this.items.length; ++i) {
  141. if (item.y > this.items[i].y) {
  142. item = this.items[i];
  143. }
  144. }
  145. return item;
  146. },
  147. scrollToFixedPosition: function () {
  148. this.scrollView.scrollToOffset(cc.v2(0, 500), 2);
  149. }
  150. });