|
@@ -0,0 +1,179 @@
|
|
|
+class ListViewAdapter {
|
|
|
+
|
|
|
+ constructor(scrollView) {
|
|
|
+ this.scrollView = scrollView;
|
|
|
+ this.content = scrollView.content;
|
|
|
+ this.scriptItems = [];
|
|
|
+ this.dataList = [];
|
|
|
+ // this.initialize();
|
|
|
+ this.updateTimer = 0;
|
|
|
+ this.updateInterval = 0.1;
|
|
|
+ this.lastContentPosY = 0; // use this variable to detect if we are scrolling up or down
|
|
|
+ this.spawnCount = 16;
|
|
|
+ this.itemHeight = 0;
|
|
|
+ this.bufferZone = 500;
|
|
|
+ this.spacing = 10;
|
|
|
+ this.scriptName = '';
|
|
|
+
|
|
|
+ this.fuckingItem = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ initialize(itemTemplate) {
|
|
|
+ console.log(this.scriptName);
|
|
|
+ let actualCount = this.dataList.length < this.spawnCount ? this.dataList.length : this.spawnCount;
|
|
|
+ // let actualCount = this.dataList.length;
|
|
|
+ if (this.itemHeight > 0) {
|
|
|
+ this.bufferZone = this.scrollView.node.height / 2 + this.content.height / 2;
|
|
|
+ this.content.height = (this.itemHeight + this.spacing) * this.dataList.length;
|
|
|
+ }
|
|
|
+ this.scriptItems = [];
|
|
|
+ this.content.removeAllChildren();
|
|
|
+ for (let i = 0; i < actualCount; i++) { // spawn items, we only need to do this once
|
|
|
+ let item = cc.instantiate(itemTemplate);
|
|
|
+ if (this.itemHeight === 0) {
|
|
|
+ this.itemHeight = item.height; // get total content height
|
|
|
+ this.bufferZone = this.scrollView.node.height / 2 + this.content.height / 2;
|
|
|
+ this.content.height = (this.itemHeight + this.spacing) * this.dataList.length;
|
|
|
+ }
|
|
|
+ this.content.addChild(item);
|
|
|
+ item.setPosition(0, -item.height * (0.5 + i) - this.spacing * (i + 1));
|
|
|
+ let itemScript = item.getComponent(this.scriptName);
|
|
|
+ // itemScript.setListViewAdapter(this);
|
|
|
+ itemScript.updateItem(this.dataList[i], i);
|
|
|
+ this.scriptItems.push(itemScript);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ getPositionInView(item) { // get item position in scrollview's node space
|
|
|
+ let worldPos = item.parent.convertToWorldSpaceAR(item.position);
|
|
|
+ let viewPos = this.scrollView.node.convertToNodeSpaceAR(worldPos);
|
|
|
+ return viewPos;
|
|
|
+ }
|
|
|
+
|
|
|
+ update(dt) {
|
|
|
+ this.updateTimer += dt;
|
|
|
+ if (this.updateTimer < this.updateInterval) return; // we don't need to do the math every frame
|
|
|
+ this.updateTimer = 0;
|
|
|
+ let buffer = this.bufferZone;
|
|
|
+ let isDown = this.content.y < this.lastContentPosY; // scrolling direction
|
|
|
+
|
|
|
+ let offset = (this.itemHeight + this.spacing) * this.scriptItems.length;
|
|
|
+
|
|
|
+ for (let i = 0; i < this.scriptItems.length; ++i) {
|
|
|
+ let viewPos = this.getPositionInView(this.scriptItems[i].node);
|
|
|
+ if (isDown) {
|
|
|
+ // if away from buffer zone and not reaching top of content
|
|
|
+ if (viewPos.y < -buffer && this.scriptItems[i].node.y + offset < 0) {
|
|
|
+ this.scriptItems[i].node.y = this.scriptItems[i].node.y + offset;
|
|
|
+ let itemScript = this.scriptItems[i];
|
|
|
+ let itemId = itemScript._itemId - this.scriptItems.length;
|
|
|
+ itemScript.updateItem(this.dataList[itemId], itemId);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // if away from buffer zone and not reaching bottom of content
|
|
|
+ if (viewPos.y > buffer && this.scriptItems[i].node.y - offset > -this.content.height) {
|
|
|
+ this.scriptItems[i].node.y = this.scriptItems[i].node.y - offset;
|
|
|
+
|
|
|
+ let itemScript = this.scriptItems[i];
|
|
|
+ let itemId = itemScript._itemId + this.scriptItems.length;
|
|
|
+ itemScript.updateItem(this.dataList[itemId], itemId);
|
|
|
+ if (itemId === (this.dataList.length - 1)) {
|
|
|
+ if (this.loadMore != undefined) {
|
|
|
+ this.loadMore();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // update lastContentPosY
|
|
|
+ this.lastContentPosY = this.content.y;
|
|
|
+ }
|
|
|
+
|
|
|
+ updateItems(dataList, itemPrefab, scriptName) {
|
|
|
+ this.scriptName = scriptName;
|
|
|
+ this.itemTemplate = itemPrefab;
|
|
|
+ this.dataList = dataList;
|
|
|
+ this.initialize(itemPrefab);
|
|
|
+ }
|
|
|
+
|
|
|
+ addData(newdataList) {
|
|
|
+ this.dataList = this.dataList.concat(newdataList);
|
|
|
+ this.content.height = (this.itemHeight + this.spacing) * this.dataList.length; // get total content height
|
|
|
+ }
|
|
|
+
|
|
|
+ setLoadMoreCallBack(loadMore) {
|
|
|
+ this.loadMore = loadMore;
|
|
|
+ }
|
|
|
+
|
|
|
+ playRemoveItemAnimation(itemScript, animCallback) {
|
|
|
+ this.dataList.splice(itemScript._itemId, 1);
|
|
|
+ this.content.height = (this.itemHeight + this.spacing) * this.dataList.length; // get total content height
|
|
|
+
|
|
|
+ let sequ = cc.sequence(cc.moveBy(0.2, -750, 0), animCallback);
|
|
|
+ itemScript.node.runAction(sequ);
|
|
|
+ }
|
|
|
+
|
|
|
+ updateItemsAndDataList(itemScript) {
|
|
|
+ let index = itemScript._itemId;
|
|
|
+ let scriptItems = this.scriptItems;
|
|
|
+
|
|
|
+ if (this.dataList.length >= scriptItems.length) {
|
|
|
+ itemScript.scheduleOnce(() => {
|
|
|
+ itemScript.node.x = 0;
|
|
|
+ }, 0.2);
|
|
|
+
|
|
|
+ for (let i = 0; i < scriptItems.length; ++i) {
|
|
|
+ let itemNode = scriptItems[i].node;
|
|
|
+ let script = scriptItems[i];
|
|
|
+ let itemId = script._itemId;
|
|
|
+ if (itemId < this.dataList.length) {
|
|
|
+ if (script._itemId > index) {
|
|
|
+ let finish = cc.callFunc(() => {
|
|
|
+ itemNode.y = itemNode.y - (this.itemHeight + this.spacing);
|
|
|
+ script.updateItem(this.dataList[itemId], itemId);
|
|
|
+ }, this);
|
|
|
+ let s = cc.sequence(cc.moveBy(0.2, 0, (this.itemHeight + this.spacing)), finish);
|
|
|
+ itemNode.runAction(s);
|
|
|
+ } else {
|
|
|
+ itemScript.scheduleOnce(() => {
|
|
|
+ script.updateItem(this.dataList[itemId], itemId);
|
|
|
+ }, 0.2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ for (let i = 0; i < scriptItems.length; ++i) {
|
|
|
+ let itemId = scriptItems[i]._itemId;
|
|
|
+ if (itemId === itemScript._itemId) {
|
|
|
+ this.scriptItems.splice(i, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < scriptItems.length; ++i) {
|
|
|
+ let itemNode = scriptItems[i].node;
|
|
|
+ let script = scriptItems[i];
|
|
|
+ if (script._itemId > index) {
|
|
|
+ let newId = script._itemId - 1;
|
|
|
+ itemNode.runAction(cc.moveBy(0.2, 0, (this.itemHeight + this.spacing)));
|
|
|
+ script.updateItem(this.dataList[newId], newId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ itemScript.node.destroy();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ removeItem(itemScript) {
|
|
|
+ let finish = cc.callFunc(() => {
|
|
|
+ this.updateItemsAndDataList(itemScript);
|
|
|
+ });
|
|
|
+ this.playRemoveItemAnimation(itemScript, finish);
|
|
|
+ }
|
|
|
+
|
|
|
+ onDestroy() {
|
|
|
+ this.scriptItems = [];
|
|
|
+ this.content.removeAllChildren();
|
|
|
+ }
|
|
|
+}
|
|
|
+module.exports = ListViewAdapter;
|