어떻게 CocosCreator 에서 List 를 만 듭 니까?

29338 단어 CocosList리스트
CocosCreator 버 전:2.3.4
cocos 는 List 구성 요소 가 없 기 때문에 스스로 써 야 합 니 다.cocos 의 example 프로젝트 에서 assets/case/02 찾기ui/05_listView 의 demo 를 개조 합 니 다.
가상 목록 을 작성 합 니 다.수직 레이아웃,수평 레이아웃,격자 레이아웃 과 Padding 의 List 가 있 습 니 다.
데모 주소:https://files-cdn.cnblogs.com/files/gamedaybyday/cocos2.3.4_ListViewDemo_Grid.7z


cocos 의 원래 레이 아웃 은 목록 을 만 들 고 100 개의 데이터 가 있 으 면 100 개의 인 스 턴 스(왼쪽 그림)가 있 습 니 다.
가상 목록 은 보 이 는 인 스 턴 스 만 존재 합 니 다.미 끄 러 질 때 반복 적 으로 사용 합 니 다.(오른쪽 그림

List 사용법
사용 방법 은 ScrollView 에 List 구성 요 소 를 추가 하면 됩 니 다.
List 의 item 목록 항목 을 content 아래 에 직접 놓 고 oList 구성 요 소 를 할당 합 니 다.item 은 item Render 에서 계승 할 대상 을 추가 하여 데이터 새로 고침 에 사용 해 야 합 니 다.

코드 에서 List 에 데 이 터 를 설정 합 니 다.

//       
let rankData = [];
 for(let i=0;i<100;i++){
      rankData.push({rank:i, name:"  "});
}
 
this.rankList.setData(rankData);
소스 코드

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
 
import ItemRender from "./ItemRender"
 
const { ccclass, property } = cc._decorator;
 
/**       */
export enum ListType {
    /**     */
    Horizontal = 1,
    /**     */
    Vertical = 2,
    /**     */
    Grid = 3
}
 
/**         */
export enum StartAxisType {
    /**     */
    Horizontal = 1,
    /**     */
    Vertical = 2,
}
 
/**
 *   
 *   cocos_example listView    
 * @author chenkai 2020.7.8
 * @example
 *  1.  cocos ScrollView  ,  List,  List    
 * 
 */
@ccclass
export default class List extends cc.Component {
 
    //====================      =========================
    /**     */
    @property({ type: cc.Node, tooltip: "   " })
    public itemRender: cc.Node = null;
 
    /**     */
    @property({ type: cc.Enum(ListType), tooltip: "    " })
    public type: ListType = ListType.Vertical;
 
    /**         */
    @property({ type: cc.Enum(StartAxisType), tooltip: "        ", visible() { return this.type == ListType.Grid } })
    public startAxis: StartAxisType = StartAxisType.Horizontal;
 
    /**     X   */
    @property({ type: cc.Integer, tooltip: "   X  ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public spaceX: number = 0;
 
    /**     Y   */
    @property({ type: cc.Integer, tooltip: "   Y  ", visible() { return this.type == ListType.Vertical || this.type == ListType.Grid } })
    public spaceY: number = 0;
 
    /**    */
    @property({ type: cc.Integer, tooltip: "   ", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
    public padding_top: number = 0;
 
    /**    */
    @property({ type: cc.Integer, tooltip: "   ", visible() { return (this.type == ListType.Vertical || this.type == ListType.Grid) } })
    public padding_buttom: number = 0;
 
    /**    */
    @property({ type: cc.Integer, tooltip: "   ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public padding_left: number = 0;
 
 
 
    @property(cc.Integer)
    public _padding: number = 0;
 
    /**    */
    @property({ type: cc.Integer, tooltip: "   ", visible() { return (this.type == ListType.Horizontal || this.type == ListType.Grid) } })
    public padding_right: number = 0;
 
    //======================      ===============================
    /**       */
    public scrollView: cc.ScrollView = null;
    /**scrollView      */
    private content: cc.Node = null;
 
    //========================     ===========================
    /**      */
    private itemDataList: Array<any> = [];
    /**         */
    private spawnCount: number = 0;
    /**           */
    private itemList: Array<cc.Node> = [];
    /**item    */
    private itemHeight: number = 0;
    /**item    */
    private itemWidth: number = 0;
    /**            */
    private itemPool: Array<cc.Node> = [];
 
    //=======================      ==========================
    /**  scrollView      ,       item    ,      scrollVIew.height/2 + item.heigt/2 + space,      item    scrollView     */
    private halfScrollView: number = 0;
    /**   content X ,     content X   ,            */
    private lastContentPosX: number = 0;
    /**   content Y ,     content Y   ,            */
    private lastContentPosY: number = 0;
    /**     */
    private gridRow: number = 0;
    /**     */
    private gridCol: number = 0;
    /**    ,  s */
    private updateTimer: number = 0;
    /**    ,  s */
    private updateInterval: number = 0.1;
    /**       */
    private bScrolling: boolean = false;
    /**      */
    private updateFun: Function = function () { };
 
    onLoad() {
        this.itemHeight = this.itemRender.height;
        this.itemWidth = this.itemRender.width;
        this.scrollView = this.node.getComponent(cc.ScrollView);
        this.content = this.scrollView.content;
        this.content.anchorX = 0;
        this.content.anchorY = 1;
        this.content.removeAllChildren();
        this.scrollView.node.on("scrolling", this.onScrolling, this);
    }
 
    /**
     *      (        ,        ,           )
     * @param itemDataList item    
     */
    public setData(itemDataList: Array<any>) {
        this.itemDataList = itemDataList.slice();
        this.updateContent();
    }
 
    /**          */
    private countListParam() {
        let dataLen = this.itemDataList.length;
        if (this.type == ListType.Vertical) {
            this.scrollView.horizontal = false;
            this.scrollView.vertical = true;
            this.content.width = this.content.parent.width;
            this.content.height = dataLen * this.itemHeight + (dataLen - 1) * this.spaceY + this.padding_top + this.padding_buttom;
            this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) + 2; //     item    ,   scrollView      item     2 
            this.halfScrollView = this.scrollView.node.height / 2 + this.itemHeight / 2 + this.spaceY; //  bufferZone,item     
            this.updateFun = this.updateV;
        } else if (this.type == ListType.Horizontal) {
            this.scrollView.horizontal = true;
            this.scrollView.vertical = false;
            this.content.width = dataLen * this.itemWidth + (dataLen - 1) * this.spaceX + this.padding_left + this.padding_right;
            this.content.height = this.content.parent.height;
            this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth + this.spaceX)) + 2;
            this.halfScrollView = this.scrollView.node.width / 2 + this.itemWidth / 2 + this.spaceX;
            this.updateFun = this.udpateH;
        } else if (this.type == ListType.Grid) {
            if (this.startAxis == StartAxisType.Vertical) {
                this.scrollView.horizontal = false;
                this.scrollView.vertical = true;
                this.content.width = this.content.parent.width;
                //  left right    ,       item, left right    0,      
                if (this.padding_left + this.padding_right + this.itemWidth + this.spaceX > this.content.width) {
                    this.padding_left = 0;
                    this.padding_right = 0;
                    console.error("padding_left padding_right  ");
                }
 
                this.gridCol = Math.floor((this.content.width - this.padding_left - this.padding_right) / (this.itemWidth + this.spaceX));
                this.gridRow = Math.ceil(dataLen / this.gridCol);
                this.content.height = this.gridRow * this.itemHeight + (this.gridRow - 1) * this.spaceY + this.padding_top + this.padding_buttom;
                this.spawnCount = Math.round(this.scrollView.node.height / (this.itemHeight + this.spaceY)) * this.gridCol + this.gridCol * 2;
                this.halfScrollView = this.scrollView.node.height / 2 + this.itemHeight / 2 + this.spaceY;
                this.updateFun = this.updateGrid_V;
            } else if (this.startAxis == StartAxisType.Horizontal) {
                this.scrollView.horizontal = true;
                this.scrollView.vertical = false;
                //     
                this.content.height = this.content.parent.height;
                //  left right    ,       item, left right    0,      
                if (this.padding_top + this.padding_buttom + this.itemHeight + this.spaceY > this.content.height) {
                    this.padding_top = 0;
                    this.padding_buttom = 0;
                    console.error("padding_top padding_buttom  ");
                }
 
                this.gridRow = Math.floor((this.content.height - this.padding_top - this.padding_buttom) / (this.itemHeight + this.spaceY));
                this.gridCol = Math.ceil(dataLen / this.gridRow);
                this.content.width = this.gridCol * this.itemWidth + (this.gridCol - 1) * this.spaceX + this.padding_left + this.padding_right;
                this.spawnCount = Math.round(this.scrollView.node.width / (this.itemWidth + this.spaceX)) * this.gridRow + this.gridRow * 2;
                this.halfScrollView = this.scrollView.node.width / 2 + this.itemWidth / 2 + this.spaceX;
                this.updateFun = this.updateGrid_H;
            }
        }
    }
 
    /**
     *     
     * @param startIndex           0     
     * @param offset     scrollView   
     */
    private createList(startIndex: number, offset: cc.Vec2) {
        //           >       ,           ,         scrollView   
        if (this.itemDataList.length > this.spawnCount && (startIndex + this.spawnCount - 1) >= this.itemDataList.length) {
            startIndex = this.itemDataList.length - this.spawnCount;
            offset = this.scrollView.getMaxScrollOffset();
 
            //           <=       ,           
        } else if (this.itemDataList.length <= this.spawnCount) {
            startIndex = 0;
        }
 
        for (let i = 0; i < this.spawnCount; i++) {
            let item: cc.Node;
            //               , item      
            if (i + startIndex < this.itemDataList.length) {
                if (this.itemList[i] == null) {
                    item = this.getItem();
                    this.itemList.push(item);
                    item.parent = this.content;
                } else {
                    item = this.itemList[i];
                }
                //                , item      
            } else {
                //item     >         
                if (this.itemList.length > (this.itemDataList.length - startIndex)) {
                    item = this.itemList.pop();
                    item.removeFromParent();
                    this.itemPool.push(item);
                }
                continue;
            }
 
            let itemRender: ItemRender = item.getComponent(ItemRender);
            itemRender.itemIndex = i + startIndex;
            itemRender.data = this.itemDataList[i + startIndex];
            itemRender.dataChanged();
 
            if (this.type == ListType.Vertical) {
                //  content   X 0,  item x  content.with/2    ,  Y 1,  item y  content     0    。  item.y= -item.height/2 ,  content   。
                item.setPosition(this.content.width / 2, -item.height * (0.5 + i + startIndex) - this.spaceY * (i + startIndex) - this.padding_top);
            } else if (this.type == ListType.Horizontal) {
                item.setPosition(item.width * (0.5 + i + startIndex) + this.spaceX * (i + startIndex) + this.padding_left, -this.content.height / 2);
            } else if (this.type == ListType.Grid) {
                if (this.startAxis == StartAxisType.Vertical) {
                    var row = Math.floor((i + startIndex) / this.gridCol);
                    var col = (i + startIndex) % this.gridCol;
                    item.setPosition(item.width * (0.5 + col) + this.spaceX * col + this.padding_left, -item.height * (0.5 + row) - this.spaceY * row - this.padding_top);
                    item.opacity = 255;
                } else if (this.startAxis == StartAxisType.Horizontal) {
                    var row = (i + startIndex) % this.gridRow;
                    var col = Math.floor((i + startIndex) / this.gridRow);
                    item.setPosition(item.width * (0.5 + col) + this.spaceX * col + this.padding_left, -item.height * (0.5 + row) - this.spaceY * row - this.padding_top);
                    item.opacity = 255;
                }
            }
        }
 
        this.scrollView.scrollToOffset(offset);
    }
 
    /**        */
    private getItem() {
        if (this.itemPool.length == 0) {
            return cc.instantiate(this.itemRender);
        } else {
            return this.itemPool.pop();
        }
    }
 
    update(dt) {
        if (this.bScrolling == false) {
            return;
        }
        this.updateTimer += dt;
        if (this.updateTimer < this.updateInterval) {
            return;
        }
        this.updateTimer = 0;
        this.bScrolling = false;
        this.updateFun();
    }
 
    onScrolling() {
        this.bScrolling = true;
    }
 
    /**     */
    private updateV() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isUp = this.scrollView.content.y > this.lastContentPosY;
        let offset = (this.itemHeight + this.spaceY) * items.length;
        for (let i = 0; i < items.length; i++) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isUp) {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex + items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.y = item.y - offset;
                }
            } else {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.y < -bufferZone && item.y + offset + this.padding_top < 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.y = item.y + offset;
                }
            }
        }
        this.lastContentPosY = this.scrollView.content.y;
    }
 
    /**     */
    private udpateH() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isRight = this.scrollView.content.x > this.lastContentPosX;
        let offset = (this.itemWidth + this.spaceX) * items.length;
        for (let i = 0; i < items.length; i++) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isRight) {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.x = item.x - offset;
                }
            } else {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.x < -bufferZone && item.x + offset + this.padding_right < this.content.width) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex + items.length;
                    itemRender.itemIndex = itemIndex;
                    itemRender.data = this.itemDataList[itemIndex];
                    itemRender.dataChanged();
                    item.x = item.x + offset;
                }
            }
        }
        this.lastContentPosX = this.scrollView.content.x;
    }
 
    /**       */
    private updateGrid_V() {
        let items = this.itemList;
        let item: cc.Node;
        let bufferZone = this.halfScrollView;
        let isUp = this.scrollView.content.y > this.lastContentPosY;
        let offset = (this.itemHeight + this.spaceY) * (this.spawnCount / this.gridCol);
        for (let i = 0; i < items.length; i++) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isUp) {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.y > bufferZone && item.y - offset - this.padding_buttom > -this.content.height) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex + (this.spawnCount / this.gridCol) * this.gridCol;
                    if (this.itemDataList[itemIndex] != null) {
                        item.y = item.y - offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.y = item.y - offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            } else {//item   ,   scrollView   , item       ,item             content    
                if (viewPos.y < -bufferZone && item.y + offset + this.padding_top < 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridCol) * this.gridCol;
                    if (this.itemDataList[itemIndex] != null) {
                        item.y = item.y + offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.y = item.y + offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            }
        }
        this.lastContentPosY = this.scrollView.content.y;
    }
 
    /**       */
    private updateGrid_H() {
        let items = this.itemList;
        let item;
        let bufferZone = this.halfScrollView;
        let isRight = this.scrollView.content.x > this.lastContentPosX;
        let offset = (this.itemWidth + this.spaceX) * (this.spawnCount / this.gridRow);
        for (let i = 0; i < items.length; i++) {
            item = items[i];
            let viewPos = this.getPositionInView(item);
            if (isRight) {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.x > bufferZone && item.x - offset - this.padding_left > 0) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex - (this.spawnCount / this.gridRow) * this.gridRow;
                    if (this.itemDataList[itemIndex] != null) {
                        item.x = item.x - offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.x = item.x - offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            } else {
                //item   ,   scrollView   , item       ,item             content    
                if (viewPos.x < -bufferZone && item.x + offset + this.padding_right < this.content.width) {
                    let itemRender: ItemRender = item.getComponent(ItemRender);
                    let itemIndex = itemRender.itemIndex + (this.spawnCount / this.gridRow) * this.gridRow;
                    if (this.itemDataList[itemIndex] != null) {
                        item.x = item.x + offset;
                        itemRender.itemIndex = itemIndex;
                        itemRender.data = this.itemDataList[itemIndex];
                        itemRender.dataChanged();
                        item.opacity = 255;
                    } else {
                        item.x = item.x + offset;
                        itemRender.itemIndex = itemIndex;
                        item.opacity = 0;
                    }
                }
            }
        }
        this.lastContentPosX = this.scrollView.content.x;
    }
 
    /**  item scrollView      */
    private getPositionInView(item) {
        let worldPos = item.parent.convertToWorldSpaceAR(item.position);
        let viewPos = this.scrollView.node.convertToNodeSpaceAR(worldPos);
        return viewPos;
    }
 
    /**       */
    public getListData() {
        return this.itemDataList;
    }
 
    /**
     *             
     * @param data   
     */
    public addItem(data: any) {
        this.itemDataList.push(data);
        this.updateContent();
    }
 
    /**
     *              
     * @param index     ,0   1 
     * @param data    
     */
    public addItemAt(index: number, data: any) {
        if (this.itemDataList[index] != null || this.itemDataList.length == index) {
            this.itemDataList.splice(index, 1, data);
            this.updateContent();
        }
    }
 
    /**
     *       
     * @param index        ,0   1 
     */
    public deleteItem(index: number) {
        if (this.itemDataList[index] != null) {
            this.itemDataList.splice(index, 1);
            this.updateContent();
        }
    }
 
    /**
     *       
     * @param index     ,0   1 
     * @param data       
     */
    public changeItem(index: number, data: any) {
        if (this.itemDataList[index] != null) {
            this.itemDataList[index] = data;
            this.updateContent();
        }
    }
 
    /**     Item    */
    private updateContent() {
        //       0 
        if (this.itemList.length == 0) {
            this.countListParam();
            this.createList(0, new cc.Vec2(0, 0));
            //         0 ,       item    
        } else {
            if (this.type == ListType.Vertical) {
                this.itemList.sort((a: any, b: any) => {
                    return b.y - a.y;
                });
            } else if (this.type == ListType.Horizontal) {
                this.itemList.sort((a: any, b: any) => {
                    return a.x - b.x;
                });
            } else if (this.type == ListType.Grid) {
                if (this.startAxis == StartAxisType.Vertical) {
                    this.itemList.sort((a: any, b: any) => {
                        return a.x - b.x;
                    });
                    this.itemList.sort((a: any, b: any) => {
                        return b.y - a.y;
                    });
                } else if (this.startAxis == StartAxisType.Horizontal) {
                    this.itemList.sort((a: any, b: any) => {
                        return b.y - a.y;
                    });
                    this.itemList.sort((a: any, b: any) => {
                        return a.x - b.x;
                    });
                }
            }
 
            this.countListParam();
 
            //     item           
            var startIndex = this.itemList[0].getComponent(ItemRender).itemIndex;
 
            if (this.type == ListType.Grid && this.startAxis == StartAxisType.Vertical) {
                startIndex += (startIndex + this.spawnCount) % this.gridCol;
            } else if (this.type == ListType.Grid && this.startAxis == StartAxisType.Horizontal) {
                startIndex += (startIndex + this.spawnCount) % this.gridRow;
            }
 
            //getScrollOffset() scrollToOffset() x     
            var offset: cc.Vec2 = this.scrollView.getScrollOffset();
            offset.x = - offset.x;
 
            this.createList(startIndex, offset);
        }
    }
 
    /**   */
    public onDestroy() {
        //     
        let len = this.itemList.length;
        for (let i = 0; i < len; i++) {
            if (cc.isValid(this.itemList[i], true)) {
                this.itemList[i].destroy();
            }
        }
        this.itemList.length = 0;
        //     
        len = this.itemPool.length;
        for (let i = 0; i < len; i++) {
            if (cc.isValid(this.itemPool[i], true)) {
                this.itemPool[i].destroy();
            }
        }
        this.itemPool.length = 0;
        //      
        this.itemDataList.length = 0;
    }
}
이상 은 CocosCreator 에서 List 를 만 드 는 방법 에 대한 상세 한 내용 입 니 다.CocosCreator List 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기