美文网首页
CocosCreator3.x开发笔记10: 列表或者背包,用s

CocosCreator3.x开发笔记10: 列表或者背包,用s

作者: 原味蛋炒饭 | 来源:发表于2023-03-02 17:04 被阅读0次

    用到复用滚动的空间,CocosCreator商城上的控件太贵了,然后打算自己做一个。
    根据网上的一些轮子,自己改了一遍,适用于CocosCreator3.x
    自用目前没什么问题,如果按我的代码使用上有什么问题,自己处理一下吧,我这个只能作为一种思路参考,大致意思都差不多就行了。刷新性能上没时间优化了,有什么思路可以评论交流一下,有空我再改哈哈哈哈哈哈。

    效果图
    ![截屏2023-03-03 16.56.43.png](https://img.haomeiwen.com/i1803099/1251962a4e2be78c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ![截屏2023-03-03 16.56.52.png](https://img.haomeiwen.com/i1803099/1d7ac8f330058a34.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    
    RecyclerView
    
    import { _decorator, Component, Node, ScrollView, game, Layout, UITransform, Vec3, EventHandler } from 'cc';
    
    import { BaseAdapter } from './BaseAdapter';
    import { BaseViewHolder } from './BaseViewHolder';
    const { ccclass, property, requireComponent } = _decorator;
    
    
    
    @ccclass('RecyclerView')
    @requireComponent(ScrollView)
    export class RecyclerView extends Component {
    
        private _adapter: BaseAdapter = null;
        public set adapter(v: BaseAdapter) {
            this._adapter = v;
            this.initLayout();
        }
        public get adapter(): BaseAdapter {
            return this._adapter;
        }
    
    
        private _scrollView: ScrollView;
        public get scrollView(): ScrollView {
            return this._scrollView;
        }
    
        private _layout: Layout;
    
    
        private _view: UITransform;
    
        /**
        * @en No layout.
        * NONE = 0,
        * @zh 禁用布局。
        */
    
        /**
         * @en Horizontal layout.
         *HORIZONTAL = 1,
         * @zh 水平布局。
         */
    
        /**
         * @en Vertical layout.
         * VERTICAL = 2,
         * @zh 垂直布局。
         */
    
        /**
         * @en Grid layout.
         * GRID = 3
         * @zh 网格布局。
         */
        private _layoutType: number;
        private _pdLeft: number;
        private _pdRight: number;
        /*上边距*/
        private _pdTop: number;
        /*下边距*/
        private _pdBottom: number;
        private _spaceX: number;
        private _spaceY: number;
        private _startAxis: number;
          /**距离scrollView中心点的距离,超过这个距离的item会被重置,一般设置为 scrollVIew.height/2 + item.heigt/2 + space,因为这个距离item正好超出scrollView显示范围 */
        private halfScrollView: number = 0;
        /**上一次content的Y值,用于和现在content的Y值比较,得出是向上还是向下滚动 */
        private lastContentPosY: number = 0;
        /**上一次content的X值,用于和现在content的X值比较,得出是向左还是向右滚动 */
        private lastContentPosX: number = 0;
        //分帧创建器
        private _gener: Generator
    
        private _isActive = true;
    
        private _pool: Map<number, Array<BaseViewHolder>> = new Map();
        private _childrens: Array<BaseViewHolder> = new Array();
        //  /*获取停止页面的第一个item的index*/
        // private lastEndStartIndex: number = 0;
    
        /**刷新的函数 */
        private updateFun: Function = function () { };
    
        onLoad() {
            this._scrollView = this.node.getComponent(ScrollView);
            let layout = this._scrollView.content.getComponent(Layout);
            if (!layout) {
                console.error("请在content里面添加item布局方式");
            }
            this._layoutType = layout.type;
            this._pdLeft = layout.paddingLeft;
            this._pdRight = layout.paddingRight;
            this._pdTop = layout.paddingTop;
            this._pdBottom = layout.paddingBottom;
            this._spaceX = layout.spacingX;
            this._spaceY = layout.spacingY;
            this._startAxis = layout.startAxis; //HORIZONTAL = 0, VERTICAL = 1
            //取消布局约束
            layout.type = Layout.Type.NONE;
            // layout.type = Layout.Type.GRID;
            this._layout = layout;
            this._view = layout.getComponent(UITransform);
            this.reset();
            this.node.on(Node.EventType.SIZE_CHANGED, this.sizeChanged, this);
            // this.scrollView.node.on(ScrollView.EventType.SCROLLING, this.onScrolling, this);
            //修改:为了防止ondestroy中this.scrollView.node为null报错,这里直接用node,recyclerview只要挂在scrollview上this.scrollView.node和this.node一样的
            this.node.on(ScrollView.EventType.SCROLLING, this.onScrolling, this);
            //SCROLL_ENDED有时候在停止后会一直调用,这里用SCROLL_ENG_WITH_THRESHOLD
            this.node.on(ScrollView.EventType.SCROLL_ENG_WITH_THRESHOLD, this.onEndWithThreshold, this);
        }
    
      
    
    
        onDestroy() {
            this.node.off(Node.EventType.SIZE_CHANGED, this.sizeChanged, this);
            // this.scrollView.node.off(ScrollView.EventType.SCROLLING, this.onScrolling, this);
            //修改:this.scrollView.node会为空
            this.node.off(ScrollView.EventType.SCROLLING, this.onScrolling, this);
            this.node.off(ScrollView.EventType.SCROLL_ENG_WITH_THRESHOLD, this.onEndWithThreshold, this);
            
            //把绘制的内容手动销毁
            this._pool.forEach((hodel) => {
                hodel.forEach((holNode) => {
                    if (holNode.node.isValid) {
                        holNode.node.destroy()
                    }
                    
                })
            })
            this._pool.clear();
            //把绘制的内容手动销毁
            this._childrens.forEach((hodel) => {
                if (hodel.node.isValid) {
                    hodel.node.destroy()
                }
            })
            this._childrens.length = 0;
            //还有node残留,把子节点都销毁
            let tem = this.node.children;
            tem.forEach((temNode) => {
                if (temNode.isValid) {
                    temNode.destroy()
                }
            })
            this._adapter = null;
            this._scrollView = null;
            this._layout = null
            this._isActive = false;
        }
    
        //重置数据
        private reset() {
            this._gener?.return("")//取消上一次的分帧任务(如果任务正在执行)
            //把绘制的内容手动销毁
            this._pool.forEach((hodel) => {
                hodel.forEach((holNode) => {
                    if (holNode.node.isValid) {
                        holNode.node.destroy()
                    }
                    
                })
            })
            this._pool.clear();
            //把绘制的内容手动销毁
            this._childrens.forEach((hodel) => {
                if (hodel.node.isValid) {
                    hodel.node.destroy()
                }
            })
            this._childrens.length = 0;
        }
    
        /**数据重置后刷新页面*/
        refreshView() {
            this.sizeChanged()
        }
        /**增删数据后刷新页面*/
        addDetleRefreshView() {
            this.countParam()
        }
        /**页面内容满了之后移动到最底部*/
        fullViewScrollToBottom() {
            if (this._view.height > this._scrollView.view.height) {
                //内容已经满了,滚动到底部
                this._scrollView.scrollToBottom()
                this.endScrollRefreshView()
            } else {
                //内容没有满,需要清空旧页面再添加
                this.clearChildrensToPool()
                this.startCreateItems(0);
            }
        }
        /**页面停止移动后,刷新页面*/
        endScrollRefreshView() {
            // console.log("endScrollRefreshView");
            //获取停止页面的第一个item的index
            let startIndex = Math.ceil(this.adapter.dataA.length*(this._scrollView.getScrollOffset().y/ this._view.height))
            
            //清空旧页面
            this.clearChildrensToPool();
            //从第一个item开始放置
            this.startCreateItems(startIndex);
            //刷新页面
            this.updateFun();
        }
        //节点大小改变
        private sizeChanged() {
            if (this.adapter) {
                this.reset();
                this.initLayout();
            }
        }
    
        //初始化面板
        private initLayout() {
            let layout = this._layout;
            if (!layout) {
                console.error("请在content里面添加item布局方式");
                return;
            }
            this.countParam();
            this.startCreateItems(0);
        }
        /*初始化scrollview数据*/
        private countParam() {
            // console.log("countParam");
    
            let type = this._layoutType;
            if (type == Layout.Type.VERTICAL) { 
                
                let bottomY = this._pdTop;
                for (let index = 0; index < this.adapter.getItemCount(); index++) {
                    this.adapter.dataA[index].size =  this.adapter.getItemSize(index)
                    if (index != 0) {
                        bottomY += this._spaceY;
                        
                    } 
                    this.adapter.dataA[index].position = new Vec3(0, -bottomY - (this.adapter.dataA[index].size.height / 2));
    
                    bottomY += this.adapter.dataA[index].size.height
                }
                bottomY += this._pdBottom;
                this._view.height = bottomY
    
                this.halfScrollView = this.scrollView.view.height / 2;
                this.updateFun = this.updateV;
                
            } else if (type == Layout.Type.HORIZONTAL) {
                
                // this._view.width = this.scrollView.view.width * this.adapter.getItemCount();
                // this._view.width = (this.adapter.getItemSize().width + this._spaceX) * this.adapter.getItemCount();
                let viewW: number = 0
                for (let index = 0; index < this.adapter.dataA.length; index++) {
                    viewW += this.adapter.getItemSize(index).width + this._spaceX
                }
                this._view.width = viewW
                this.halfScrollView = this.scrollView.view.width / 2;
                this.updateFun = this.updateH;
            } else if (type == Layout.Type.GRID) {
                let startAxis = this._startAxis;
                /**
                 * @en The horizontal axis.
                 * HORIZONTAL = 0,
                 * @zh 进行水平方向布局。
                 */
    
                /**
                 * @en The vertical axis.
                 * VERTICAL = 1
                 * @zh 进行垂直方向布局。
                 */
                if (startAxis == 0) {
    
                } else if (startAxis == 1) {
    
                    let bottomY = this._pdTop;
                    let bottomX = this._pdLeft;
                    let maxH = 0;
                    for (let index = 0; index < this.adapter.getItemCount(); index++) {
                        
                        this.adapter.dataA[index].size =  this.adapter.getItemSize(index)
                        
                        if ((bottomX + this.adapter.getItemSize(index).width + this._pdRight) > this.scrollView.view.width) {
                            bottomX = this._pdLeft;
                            bottomY += this.adapter.getItemSize(index).height + this._spaceY;
                        } 
    
                        this.adapter.dataA[index].position = new Vec3(bottomX + (this.adapter.dataA[index].size.width / 2) - this.scrollView.view.width/2, -bottomY - (this.adapter.dataA[index].size.height / 2));
    
                        bottomX += this.adapter.getItemSize(index).width + this._spaceX;
    
                        maxH = this.adapter.dataA[index].size.height
                    }
                    bottomY += maxH + this._pdBottom;
               
                    this._view.height = bottomY
                    this.halfScrollView = this.scrollView.view.height / 2;
                    this.updateFun = this.updateGridV;
                }
            }
        }
    
        /**
         * 
         * @param startIndex 创建的起始节点
         */
        private startCreateItems(startIndex: number) {
            // console.log("startCreateItems");
            //取消上一次的分帧任务(如果任务正在执行)
            this._gener?.return("");
    
            if (startIndex < 0) {
                startIndex = 0;
            }
    
            let type = this._layoutType;
            let maxNum = this.adapter.getItemCount();
            let total = 0;
            if (type == Layout.Type.VERTICAL) {
                total = Math.abs(this._view.height);
            } else if (type == Layout.Type.HORIZONTAL) {
                total = Math.abs(this._view.width)
            } else if (type == Layout.Type.GRID) {
                if (this._startAxis == 0) {
    
                } else if (this._startAxis == 1) {
                    total = Math.abs(this._view.height);
                }
            }
            this._gener = this.getGeneratorLength(total, (i, gener) => {
                if (!this._isActive) {
                    gener?.return("")
                    return false;
                }
    
                let index = startIndex + i;
                if (index >= maxNum) {
                    //超出范围 则直接退出
                    gener?.return("")
                    return false
                }
                let item: BaseViewHolder;
                let itemType = this.adapter.getType(index);
                // console.log("startCreateItems_getItem");
                item = this.getItem(itemType, index);
                item.itemIndex = index;
    
                this._layout.node.addChild(item.node);
    
    
                if (type == Layout.Type.VERTICAL) {
                    item.node.position = new Vec3(item.node.position.x, this.adapter.dataA[index].position.y)
                    
                    if (!this.isInWindow(item)) {
                        this._childrens.push(item);
                        gener?.return("")
                        //创建结束
                        return false;
                    }
                } else if (type == Layout.Type.HORIZONTAL) {
                    let leftX = this._pdLeft;
                    let lastItem = this._childrens[this._childrens.length - 1];
                    if (lastItem) {
                        leftX = lastItem.node.position.x + lastItem.view.width / 2
                            + this._spaceX;
    
                    }
                    item.node.position = new Vec3(leftX + item.view.width / 2,
                        item.node.position.y);
                    if (!this.isInWindow(item)) {
                        this._childrens.push(item);
                        gener?.return("")
                        return false;
                    }
                    if (i == maxNum - 1) {
                        this._view.width
                            = Math.abs(item.node.position.x) + item.view.width / 2 + this._pdRight;
                    }
                } else if (type == Layout.Type.GRID) {
                    let startAxis = this._startAxis;
    
                    if (startAxis == 0) {
                        //水平
                    } else if (startAxis == 1) {
                        //垂直
                        item.node.position = new Vec3(this.adapter.dataA[index].position.x, this.adapter.dataA[index].position.y)
                    }
                    if (!this.isInWindow(item)) {
                        this._childrens.push(item);
                        gener?.return("")
                        return false;
                    }
                }
    
                this._childrens.push(item);
                return true;
            }, this._gener)
    
            this.exeGenerator(this._gener, 4);
        }
    
        private createNextItem() {
            // console.log("createNextItem");
            let lastItem = this._childrens[this._childrens.length - 1];
            if (!lastItem) {
                return
            }
            let index = lastItem.itemIndex + 1;
            if (index >= this.adapter.getItemCount()) {
                return;
            }
            if (this.isInWindow(lastItem)) {
                let item: BaseViewHolder;
                let type = this._layoutType;
                let itemType = this.adapter.getType(index);
                item = this.getItem(itemType, index);
                item.itemIndex = index;
                this._layout.node.addChild(item.node);
    
    
                if (type == Layout.Type.VERTICAL) {
                    item.node.position = new Vec3(item.node.position.x, this.adapter.dataA[index].position.y)
                } else if (type == Layout.Type.HORIZONTAL) {
                    let leftX = this._pdLeft;
                    let lastItem = this._childrens[this._childrens.length - 1];
                    if (lastItem) {
                        leftX = lastItem.node.position.x + lastItem.view.width / 2
                            + this._spaceX;
                    }
                    item.node.position = new Vec3(leftX + item.view.width / 2,
                        item.node.position.y);
                    if (index == this.adapter.getItemCount() - 1) {
                        this._view.width
                            = Math.abs(item.node.position.x) + item.view.width / 2 + this._pdRight;
                    }
                } else if (type == Layout.Type.GRID) {
                    // if (this._startAxis == 0) {
    
                    // } else if (this._startAxis == 1) {
                        item.node.position = new Vec3(this.adapter.dataA[index].position.x, this.adapter.dataA[index].position.y)
                    // }
                }
    
                this._childrens.push(item);
                this.createNextItem();
            }
        }
    
        private createPreviousItem() {
            // console.log("createPreviousItem");
            let firstItem = this._childrens[0];
            if (!firstItem) {
                return
            }
            let index = firstItem.itemIndex - 1;
            if (index < 0) {
                return
            }
            if (this.isInWindow(firstItem)) {
                let item: BaseViewHolder;
                let type = this._layoutType;
                let itemType = this.adapter.getType(index);
                item = this.getItem(itemType, index);
                item.itemIndex = index;
                this._layout.node.addChild(item.node);
    
    
                if (type == Layout.Type.VERTICAL) {
                    item.node.position = new Vec3(item.node.position.x, this.adapter.dataA[index].position.y);
                } else if (type == Layout.Type.HORIZONTAL) {
                    let leftX = firstItem.node.position.x - firstItem.view.width / 2 - this._spaceX;
                    item.node.position = new Vec3(leftX - item.view.width / 2, item.node.position.y);
                }
                
                this._childrens.unshift(item);
                this.createPreviousItem();
            }
        }
    
        private createGrildPreviousItem() {
    
            let firstItem = this._childrens[0];
            if (!firstItem) {
                return
            }
            let index = firstItem.itemIndex - 1;
            if (index < 0) {
                return
            }
            if (this.isInWindow(firstItem)) {
                let item: BaseViewHolder;
                let type = this._layoutType;
                let itemType = this.adapter.getType(index);
                item = this.getItem(itemType, index);
                item.itemIndex = index;
                this._layout.node.addChild(item.node);
    
                item.node.position = new Vec3(this.adapter.dataA[index].position.x, this.adapter.dataA[index].position.y)
    
                this._childrens.unshift(item);
                this.createGrildPreviousItem();
            }
        }
    
    
    
        //判断是否在窗口
        private isInWindow(item: BaseViewHolder): boolean {
            let point = this.getPositionInView(item);
            let type = this._layoutType;
            let startAxis = this._startAxis;
            if (type == Layout.Type.VERTICAL) {
                if (point.y - item.view.height / 2 > this.halfScrollView
                    || point.y + item.view.height / 2 < -this.halfScrollView) {
               
                    return false;
                }
            
                
            } else if (type == Layout.Type.HORIZONTAL) {
                if (point.x + item.view.width / 2 < -this.halfScrollView
                    || point.x - item.view.width / 2 > this.halfScrollView) {
                    return false;
                }
            } else if (type == Layout.Type.GRID) {
                if (startAxis == 0) {
                    if (point.x + item.view.width / 2 < -this.halfScrollView
                        || point.x - item.view.width / 2 > this.halfScrollView) {
                        return false;
                    }
                } else if (startAxis == 1) {
                    if (point.y - item.view.height / 2 > this.halfScrollView
                        || point.y + item.view.height / 2 < -this.halfScrollView) {
                        return false;
                    }
                }
            }
            return true;
        }
    
    
        /**获取item在scrollView的局部坐标 */
        private getPositionInView(item: BaseViewHolder): Vec3 {
            let worldPos = this._view.convertToWorldSpaceAR(item.node.position);
            let viewPos = this.scrollView.view.convertToNodeSpaceAR(worldPos);
            return viewPos;
        }
    
    
        /**获取一个列表项 */
        private getItem(type, index) {
            let child: BaseViewHolder;
            let datas = this._pool.get(type);
            if (datas && datas.length) {
                child = datas.pop();
            } else {
                child = this.adapter.onCreateViewHolder(index)
            }
            this.adapter.onBindViewHolder(child, index);
            return child;
        }
        /**从页面移除后,放入pool*/
        private removeItem(item: BaseViewHolder) {
            if (!item) { return }
            item.node.removeFromParent();
    
            let type = this.adapter.getType(item.itemIndex);
            let datas = this._pool.get(type);
            if (!datas) {
                datas = new Array();
            }
            datas.push(item);
            // this._pool[type] = datas;
            //修改:this._pool[type] = datas 不能在没有生产键值对的情况下使用
            this._pool.set(type, datas)
        }
        /**直接放入pool*/
        private poolPushItem(item: BaseViewHolder) {
            if (!item) { return }
    
            let type = this.adapter.getType(item.itemIndex);
            let datas = this._pool.get(type);
            if (!datas) {
                datas = new Array();
            }
            datas.push(item);
            //修改:this._pool[type] = datas 不能在没有生产键值对的情况下使用
            this._pool.set(type, datas)
        }
    
        /** 
        *清除页面上的item到Pool,只remove不在页面上的childrens,
        */
        public clearChildrensToPool() {
            let poolTemp: BaseViewHolder[] = []
            this._childrens.forEach(element => {
                let viewPos = this.getPositionInView(element);
                //如果item超过上边界 那么就移除
                if (viewPos.y - element.view.height / 2 > this.halfScrollView) {
                    //直接remove
                    this.removeItem(element);
                } else {
                    //不直接remove
                    poolTemp.push(element)
                }
            });
            poolTemp.forEach(element => {
                //不直接remove pool
                this.poolPushItem(element);
            });
            this._childrens.length = 0
        }
        /**清除页面上的item到Pool,并全部remove*/
        public clearAllRemoveChildrensToPool() {
             this._childrens.forEach(element => {
                this.removeItem(element);
            });
            this._childrens.length = 0
        }
    
        public updateV() {
            // console.log("updateV");
            
            
            let isUp = this._layout.node.position.y > this.lastContentPosY;
            let isDown = this._layout.node.position.y < this.lastContentPosY;
            let childs = this._childrens;
            for (let i = 0; i < childs.length; ++i) {
                let item = childs[i];
                let viewPos = this.getPositionInView(item);
                if (childs.length <= 1) {
                    //必须要剩一个 不然就全部被删除了
                    break
                }
                if (isUp) {
                    //如果item超过上边界 那么就移除
                    if (viewPos.y - item.view.height / 2 > this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                } else if (isDown) {
                    if (viewPos.y + item.view.height / 2 < -this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                }
            }
    
            if (isUp) {
                //创建下一个
                this.createNextItem();
            } else if (isDown) {
                //创建上一个
                this.createPreviousItem();
            }
            this.lastContentPosY = this._layout.node.position.y;
        }
    
        public updateH() {
            let isLeft = this._layout.node.position.x < this.lastContentPosX;
            let childs = this._childrens;
            for (let i = 0; i < childs.length; ++i) {
                let item = childs[i];
                let viewPos = this.getPositionInView(item);
                if (childs.length <= 1) {
                    break
                }
                if (isLeft) {
                    //如果item超过左边界 那么就移除
                    if (viewPos.x + item.view.width / 2 < -this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                } else {
                    if (viewPos.x - item.view.width / 2 > this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                }
            }
            if (isLeft) {
                //创建下一个
                this.createNextItem();
            } else {
                //创建上一个
                this.createPreviousItem();
            }
            this.lastContentPosX = this._layout.node.position.x;
        }
    
        public updateGridV() {
            // console.log("updateGridV");
    
            // if (startAxis == 0) {
    
            // } else if (startAxis == 1) {
    
            // }
            
            let isUp = this._layout.node.position.y > this.lastContentPosY;
            let childs = this._childrens;
    
            for (let i = 0; i < childs.length; ++i) {
                let item = childs[i];
                let viewPos = this.getPositionInView(item);
                if (childs.length <= 1) {
                    //必须要剩一个 不然就全部被删除了
                    break
                }
                if (isUp) {
                    //如果item超过上边界 那么就移除
                    if (viewPos.y - item.view.height / 2 > this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                } else {
                    if (viewPos.y + item.view.height / 2 < -this.halfScrollView) {
                        this.removeItem(item);
                        childs.splice(i, 1);
                        i--;
                    }
                }
            }
           
    
            if (isUp) {
                //创建下一个
                this.createNextItem();
            } else {
                //创建上一个
                this.createGrildPreviousItem();
            }
            this.lastContentPosY = this._layout.node.position.y;
        }
    
    
        /**是否滚动容器 */
        private bScrolling: boolean = false;
        lateUpdate(dt) {
            if (this.bScrolling == false) {
                return;
            }
            this.bScrolling = false;
            this.updateFun();
        }
    
        public onScrolling(ev: Event = null) {
            this.bScrolling = true;
        }
    
        public onEndWithThreshold(ev: Event = null) {
            //移动停止回调
            this.endScrollRefreshView()
        }
    
        /** 分帧加载 */
        private * getGeneratorLength(length: number, callback: Function, ...params: any): Generator {
            for (let i = 0; i < length; i++) {
                let result = callback(i, ...params)
                if (result) {
                    yield
                } else {
                    return
                }
            }
        }
    
        /** 分帧执行 */
        private exeGenerator(generator: Generator, duration: number) {
            return new Promise<void>((resolve, reject) => {
                let gen = generator
                let execute = () => {
                    let startTime = new Date().getTime()
                    for (let iter = gen.next(); ; iter = gen.next()) {
                        if (iter == null || iter.done) {
                            resolve()
                            return
                        }
                        if (new Date().getTime() - startTime > duration) {
                            setTimeout(() => execute(), game.deltaTime * 1000)
                            return
                        }
                    }
                }
                execute()
            })
        }
    }
    
    
    BaseViewHolder
    
    
    import { _decorator, Node, UITransform, Size, Vec3 } from 'cc';
    
    export class BaseScrollData {
        data: any
        size: Size
        position: Vec3
    
        constructor(data: any, size: Size, position: Vec3) {
            this.data = data
            this.size = size
            this.position = position
        }
    }
     
    export abstract class BaseViewHolder {
    
        public node: Node;
    
        public view: UITransform;
    
        public itemIndex:number;
    
        constructor(node: Node){
            this.node = node;
            this.view = node.getComponent(UITransform);
        }
    
    
        abstract onBind(data:any, index: number);
    }
    
    
    BaseAdapter
    
    import { _decorator, Component, Node, Size } from 'cc';
    import { BaseViewHolder, BaseScrollData } from './BaseViewHolder';
    const { ccclass, property } = _decorator;
    
    
     
    @ccclass('BaseAdapter')
    export abstract class BaseAdapter extends Component {
         //节点数量
         abstract getItemCount(): number;
         //节点宽高
         abstract getItemSize(index: number): Size;
         //数据源
         abstract dataA: BaseScrollData[]
         //创建节点
         abstract onCreateViewHolder(index: number): BaseViewHolder;
     
         //绑定节点信息
         abstract onBindViewHolder(holder: BaseViewHolder, index: number);
         
        // 对不同的数据进行分类
         abstract getType(index:number):number;
     
         private _dataDirty = false;
         public get dataDirty() : boolean {
             return this._dataDirty;
         }
         //数据刷新
         public notifyDataSetChanged(){
             this._dataDirty = true;
         }
         //数据刷新完成
         public dataRefreshComplete(){
             this._dataDirty = false;
         }
    }
    
    

    相关文章

      网友评论

          本文标题:CocosCreator3.x开发笔记10: 列表或者背包,用s

          本文链接:https://www.haomeiwen.com/subject/epbjldtx.html