CCVirtualGridList - Cocos Creator 虛擬列表

一 控件介紹

CCVirtualGridList是基于Cocos Creator ScrollView + Layout 編寫的一個(gè)具有虛擬布局特點(diǎn)的滾動(dòng)列表控制容器。支持平滑滾動(dòng)顯示大量數(shù)據(jù)對(duì)象,圖片元素可以實(shí)現(xiàn)異步按幀加載,保證滾動(dòng)平滑。具有滾動(dòng)翻頁功能自適應(yīng)寬度顯示多列,單項(xiàng)選擇,局部更新等實(shí)用功能。

Cocos Creator 引擎中提供了一個(gè)常規(guī)的滾動(dòng)控制容器——ScrollView,實(shí)現(xiàn)基本滾動(dòng)控制。但是缺少與之配合的List控件來實(shí)現(xiàn)虛擬布局功能,需要開發(fā)者手動(dòng)擴(kuò)展,在這里就提供一個(gè)實(shí)現(xiàn)虛擬布局功能的擴(kuò)展列表控件,是參照Egret中的List控件的接口方式來實(shí)現(xiàn)。


demo_screenshot_1.png

二 虛擬布局原理

虛擬布局的原理其實(shí)很簡單,就是只加載和顯示可視區(qū)域的列表內(nèi)容,可視區(qū)域外的并沒有實(shí)體控件被實(shí)例化。以滾動(dòng)事件驅(qū)動(dòng),動(dòng)態(tài)滾動(dòng)并復(fù)用可視區(qū)域內(nèi)的列表模板,切換數(shù)據(jù)顯示,看上去像一個(gè)完整的列表在上下滾動(dòng),由于此種設(shè)計(jì)實(shí)例化控件少,所以內(nèi)存占用極少,drawcall數(shù)量低而且穩(wěn)定,所以現(xiàn)在被普遍應(yīng)用。但是虛擬布局的核心不僅在于此,由于需要不停地切換顯示內(nèi)容,如何將素材轉(zhuǎn)換的更快速,更平滑才是虛擬列表的關(guān)鍵。CCVirtualGridList在VirtualGridListBaseItem 中提供自己的加載圖片的方法——loadImage,實(shí)現(xiàn)異步按幀加載,保證列表滾動(dòng)流暢度,又能有效利用緩存。

三 VirtualGridList 使用

使用控件非常簡單,只需要拷貝demo項(xiàng)目中三個(gè)文件VirtualGridList.prefab,VirtualGridList.js,VirtualGridListBaseItem.js 到您的工程中Prefabs文件夾中即可。使用之前將VirtualGridList.prefab拖入畫面中, 列表單元控制組件繼承 VirtualGridListBaseItem 就可以。

四 API說明

1. VirtualGridList 啟動(dòng)參數(shù)

啟動(dòng)參數(shù)可以在creator 圖形化界面填入,但是為了不受預(yù)制體的維護(hù)影響,建議通過初 始化腳本接口傳入啟動(dòng)參數(shù)。

virtualGridList.initGridList(itemTemplatePrefab, itemComponentName, options?)

參數(shù)

- itemTemplatePrefab    cc.Prefab   列表單元顯示控件
- itemComponentName     String      列表單元顯示控件控制器名稱, 必須繼承 VirtualGridListBaseItem
- options? {                     
    paddingTop?: Number             列表距離上邊緣距離 默認(rèn)為0
    paddingBottom?: Number          列表距離下邊緣距離 默認(rèn)為0
    spacingX?: Number               列間距 默認(rèn)為3
    spacingY?: Number               行間距 默認(rèn)為3
    columnNum?: Number              列數(shù) 默認(rèn)為0,列數(shù)自動(dòng)適配容器寬度
    useVirtualList?: Boolean        是否啟用虛擬列表 默認(rèn)為true
    emptyTip?: cc.String            沒有數(shù)據(jù)顯示提示
    cacheImage?: Boolean            通過virtualGridListBaseItem.loadImage()方法加載的
                                      圖片,自動(dòng)緩存,控件回收后,圖片緩存將被全部釋放。
}

2. VirtualGridList 功能接口

createItemsDisplayList(dataList: any[]): void

首次創(chuàng)建顯示列表, dataList為數(shù)據(jù)數(shù)組

appendItemsToDisplayList(dataList: any[]): void

追加顯示列表, dataList為追加的數(shù)據(jù)數(shù)組,適用于滾動(dòng)翻頁

getDataList(): any[]

獲取數(shù)據(jù)數(shù)組

getTemplateItems(): cc.Prefab[]

獲取顯示對(duì)象列表

clearList(): void

清空列表

findItemDisplayByData(data: any): cc.Prefab

根據(jù)數(shù)據(jù)對(duì)象查找對(duì)應(yīng)的顯示對(duì)象,當(dāng)開啟虛擬列表的時(shí)候,返回對(duì)象可能不存在

getImageFromCache(key: String): cc.Texture2D

獲取緩存圖片

addScrollToBottomEventHandler(handler: Function, thisObj: any): void

注冊(cè)滾動(dòng)至底部回調(diào)方法 當(dāng)useVirtualList=false 時(shí)不可用

refreshItemDisplays(some?: any[]): void

修改數(shù)據(jù)后,刷新列表顯示,some代表指定刷新的對(duì)象, 不傳則刷新全部。

isTop(): Boolean

判斷是否滾動(dòng)至頂部

scrollToTop(): void

滾動(dòng)至頂部

scrollToFixedPosition(itemIndex: Number, sec?: Number): void

滾動(dòng)到固定位置 itemIndex代表滾動(dòng)至指定顯示對(duì)象的索引, sec為滾動(dòng)動(dòng)畫時(shí)長

3. VirtualGridListBaseItem 顯示單元基類 (必須繼承) 接口

data: any

數(shù)據(jù)對(duì)象。來自要顯示的數(shù)據(jù)列表中的一條,每一條顯示單元控件,都對(duì)應(yīng)一條數(shù)據(jù)對(duì)象,當(dāng)useVirtualLayout= true 的時(shí)候,單元控件對(duì)應(yīng)的data數(shù)據(jù)對(duì)象不固定,會(huì)滾動(dòng)切換。

dataChanged(): void

子類可覆蓋方法,自定義顯示方法,當(dāng)滾動(dòng)交替或初始化的時(shí)候觸發(fā)。當(dāng)useVirtualLayout= true 的時(shí)候,每一個(gè)顯示單元控件都是滾動(dòng)復(fù)用的,所以對(duì)應(yīng)的Component組件也是復(fù)用的,所以不要在其內(nèi)部記錄與某一條數(shù)據(jù)對(duì)應(yīng)的變量或?qū)傩浴?/p>

dataChanged() {
        this._super();
        const data = this.data;
        this.loadImage(data.pic, this._showImg, this); // 建議所有圖片通過loadImage加載,可以自動(dòng)緩存,并且異步按幀加載,不卡頓
        this.lbItemName.getComponent(cc.Label).string = data.name;
        this.lbDate.getComponent(cc.Label).string = data.date;
    }

getItemIndex(): Number

獲取現(xiàn)實(shí)對(duì)象在隊(duì)列中的索引

onSelect(): void

子類可覆蓋方法,點(diǎn)選觸發(fā)事件,只支持單選

onUnselect(): void

子類可覆蓋方法,如果當(dāng)前為選中狀態(tài),當(dāng)其他單元被點(diǎn)選觸發(fā)此事件

onLeave(): void

子類可覆蓋方法,當(dāng)控件滑動(dòng)離開可視區(qū)的時(shí)候觸發(fā) 當(dāng)useVirtualList=false 時(shí)不可用

onEnter(): void

子類可覆蓋方法,當(dāng)控件滑動(dòng)進(jìn)入可視區(qū)的時(shí)候觸發(fā) 當(dāng)useVirtualList=false 時(shí)不可用

loadImage(pic: String, cb: Function, thisObj: any): void

VirtualGridList 提供的異步加載圖片, 自動(dòng)緩存。pic: 圖片地址, cb: 圖片加載后的回調(diào)方法,thisObj: 回調(diào)方法this對(duì)象

五 顯示列表

initGridList(){
        this._gridListController.initGridList(this.itemTemplate, 'ItemDisplayController', {
            paddingTop: 10,
            paddingBottom: 100,
            spacingY: 5,
            emptyTip: '什么也沒有啊',
            columnNum: this._currentColumn,
            useVirtualList: true
        });
        this._gridListController.addScrollToBottomEventHandler(this._nextPage, this); //注冊(cè)翻頁事件

        this._showList();
    },
  showList(pageNo, itemCount) {
        pageNo = pageNo || 1;
        itemCount = itemCount || 29;
        let list = [];
        let total = pageNo * itemCount;
        let picIndex = 0;
        for (let i = (pageNo - 1) * itemCount + 1; i <= total; i++) {
            picIndex++;
            let item = {
                pic: "avatar/avatar_" + picIndex,
                date: "3/9 12:00",
                name: i + '_測試郵件'
            }
            list.push(item);
        }
        this._dataList = this._dataList ? this._dataList.concat(list) : list; // 滾動(dòng)翻頁需要合并數(shù)據(jù)數(shù)組

        this._gridListController.appendItemsToDisplayList(list);
    }
demo_screenshot_2.png

demo_screenshot_3.png

demo_screenshot_1.png

六 配合CCButtonDropdownList可以擴(kuò)展實(shí)現(xiàn)帶有虛擬布局的下拉列表

CCVirtualGridList 源碼 + Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1,NSObject中description屬性的意義,它可以重寫嗎?答案:每當(dāng) NSLog(@"")函數(shù)中出現(xiàn) ...
    eightzg閱讀 4,351評(píng)論 2 19
  • 廢話不多說,直接上干貨 ---------------------------------------------...
    小小趙紙農(nóng)閱讀 3,691評(píng)論 0 15
  • 1.badgeVaule氣泡提示 2.git終端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夾內(nèi)容...
    i得深刻方得S閱讀 4,987評(píng)論 1 9
  • 窗外的風(fēng)在怒吼著,從窗而入的風(fēng)吹在臉上涼簌簌,很爽,牙疼貌似也因?yàn)轱L(fēng)的吹拂感覺好一點(diǎn)了,在風(fēng)的陪伴下我敲著今天的作...
    花緣過客閱讀 457評(píng)論 0 0
  • 中國畫的分類 1.山水畫 山水畫最早起源于秦漢,后來經(jīng)過各個(gè)朝代的發(fā)展,各朝代主要代表性人物及作品如下: 2.人物...
    我是森森閱讀 767評(píng)論 0 0

友情鏈接更多精彩內(nèi)容