cocos ListView 重写优化

listView 可以复用 使用
 

listview_table 为cocos的scrollview   listItem 为单个item / listItem 每一个有三个小的组件
this.listview_table.activeGCItems(this.listItem);
// updateTableItem  处理每一个Item的方法。
this.listview_table.setFlashFunc(this.updateTableItem.bind(this));

this.listview_table.removeAllChildren();
this.listview_table.removeAllItemsWithGC();
var data = clubData.tables.slice();
let itmeData;
for(let i =0; i< Math.ceil(data.length/3); i++) {
    itmeData = [];
    for(var j = i*3;j<i*3+3;j++){
        if(j < data.length){
            itmeData.push(data[j]);
        }
    }
    // 插入每一条Item数据
    this.listview_table.insertGCItem(itmeData,0,true);
}

// 可使用分页数据处理, 先停止滑动,,然后重置所有数据即可, 所需要的处理的就是记录 content的位置,重置到滑动的位置
this.listview_table.stopAutoScroll();
this.listview_table.resetAllData(splitArrayByNum(clubData.members, 3 ));

 
/**
 * @method Item 修改数据方法
 * @param {Function} 必传参数 item对像 data 数据
 */
ccui.ListView.prototype.setFlashFunc = function(func) {
    this.flashFunc = func;
};

/**
 * @method 启用回收机制
 * @param {Object} prefab理解为预置体
 */
ccui.ListView.prototype.activeGCItems = function(prefab) {
    this.gcPool = [];//回收池
    this.usePool = [];//使用池
    this.flashFunc = null;
    if(this._updateGCItems) this.unschedule(this._updateGCItems);
    //计算大小
    if(!prefab) return;
    this.prefab = prefab;
    var ps = prefab.getContentSize();
    var cs = this.getContentSize();
    var mgnPx = this.getItemsMargin();
    var d = this.getDirection();// 0:水平 1:垂直
    var cloneItemNum = 0;
    if(d == 1) {
        cloneItemNum = parseInt(cs.height / (ps.height + mgnPx)) + 4;
    } else if(d == 0) {
        cloneItemNum = parseInt(cs.width / (ps.width + mgnPx)) + 4;
    }
    for(var i = 0; i < cloneItemNum; i++) {
        var clone = prefab.clone();
        clone.visible = true;
        clone.x = 0;
        clone.y = 0;
        clone.retain();
        this.gcPool.push(clone);
    }
    this.schedule(this._updateGCItems);
};

/**
 * @method 插入回收的对象数据
 * @param {Object} itemInfo
 * @param {Number} idx
 * @param {Boolean} isPushBack
 */
ccui.ListView.prototype.insertGCItem = function(itemInfo,idx,isPushBack) {
    var isDebug = false;
    var s = this.prefab.getContentSize();
    var c = this.getChildren();
    var vc  = c.filter(function(e){ return !e.enabled;});
    vc = vc.reverse();
    this.itemMaxindex = this.itemMaxindex || 0;
    if(vc.length){
        vc[0].enabled = true;
        vc[0].itemInfo = itemInfo;
        return;
    }
    var layout = ccui.Layout.create();
    layout.attr({
        x: 0,
        y: 0,
        anchorX: this.prefab.anchorX,
        anchorY: this.prefab.anchorY
    });
    layout.setContentSize(s.width, s.height);
    if(isDebug) {
        layout.setBackGroundColorType(ccui.Layout.BG_COLOR_SOLID);
        layout.setBackGroundColor(cc.color(255, c.length*2, 0));
        layout.setBackGroundColorOpacity(200);
    }
    layout.itemInfo = itemInfo;
    if(!isPushBack) {
        layout.item_index = idx;
        for (let index = idx; index < this.itemMaxindex; index++) {
            if(c[index]){
                c[index].item_index = c[index].item_index + 1;
            }
        }
        this.insertCustomItem(layout,idx);
    }
    else {
        layout.item_index = this.itemMaxindex;
        this.pushBackCustomItem(layout);
    }
    this.itemMaxindex++;
};

/**
 * @method 更新回收items
 * @param {Number} dt
 */
ccui.ListView.prototype._updateGCItems = function(dt) {
    if(!this.gcPool || !this.usePool) return;
    var c = this.getChildren();
    var d = this.getDirection();// 0:水平 1:垂直
    var minP = 0, maxP = 0,boundOff = 0;
    if(d == 1) {
        boundOff = this.prefab.getContentSize().height * 1.6;
        minP = this.convertToWorldSpace(cc.p(0,- this.anchorY * this.getContentSize().height - boundOff)).y;
        maxP = this.convertToWorldSpace(cc.p(0,(1 - this.anchorY) * this.getContentSize().height + boundOff)).y;
    } else if(d == 0) {
        boundOff = this.prefab.getContentSize().width * 1.6;
        minP = this.convertToWorldSpace(cc.p(- this.anchorX * this.getContentSize().width - boundOff,0)).x;
        maxP = this.convertToWorldSpace(cc.p((1- this.anchorX) * this.getContentSize().width + boundOff,0)).x;
    }
    for(var i = 0; i < c.length; i++) {
        var item = c[i],p0 = 0,p1 = 0;
        if(d == 1) {
            p0 = item.convertToWorldSpace(cc.p(0,- item.anchorY * item.getContentSize().height)).y;
            p1 = item.convertToWorldSpace(cc.p(0,(1 - item.anchorY) * item.getContentSize().height)).y;
        } else if(d == 0) {
            p0 = item.convertToWorldSpace(cc.p(- item.anchorX * item.getContentSize().width,0)).x;
            p1 = item.convertToWorldSpace(cc.p((1 - item.anchorX) * item.getContentSize().width,0)).x;
        }
        var ci = item.getChildren();
        if(p1 < minP || p0 > maxP) {
            if(ci[0]) {
                ci[0].removeFromParent();
                this.gcPool.push(ci[0]);
                var idx = this.usePool.indexOf(ci[0]);
                if(idx > -1) this.usePool.splice(idx,1);
            }
        } else if(!ci[0]){
            var one = this.gcPool.pop();
            if(!one) {
                var one = this.prefab.clone();
                one.visible = true;
                one.x = 0;
                one.y = 0;
                one.retain();
            }
            if(one && item.itemInfo && cc.sys.isObjectValid(one)) {
                item.addChild(one);
                if(this.flashFunc) {
                    one.item_index = item.item_index;
                    this.flashFunc(one,item.itemInfo);
                }
                this.usePool.push(one);
            }
        }
    }
};

ccui.ListView.prototype.onExit = function() {
    ccui.Widget.prototype.onExit.call(this);
    if(this._updateGCItems) this.unschedule(this._updateGCItems);
    var pool = [].concat(this.gcPool,this.usePool);
    pool.forEach(function(item) { if(item) item.release();});
    delete this.gcPool;
    delete this.usePool;
};

ccui.ListView.prototype.removeAllItemsWithGC = function() {
    var c = this.getChildren();
    for(var i = 0; i < c.length; i++) {
        c[i].removeAllChildren();
        c[i].enabled = false;
        c[i].itemInfo = null;
    }
    if(this.gcPool && this.usePool) {
        this.gcPool = this.gcPool.concat(this.usePool);
        this.usePool.length = 0;
    }
    this.itemMaxindex = 0;
};

ccui.ListView.prototype.removeItemWithGC = function(index) {
    var c = this.getChildren().filter(function(e) { return e.enabled;});
    for(var i = 0; i < c.length; i++) {
        if(index == i) {
            var ci = c[i].getChildren();
            if(ci[0]) {
                c[i].removeAllChildren();
                this.gcPool.push(ci[0]);
                var idx = this.usePool.indexOf(ci[0]);
                if(idx > -1) this.usePool.splice(idx,1);
            }
            c[i].enabled = false;
            c[i].itemInfo = null;
            break;
        }
    }
};

ccui.ListView.prototype.refreshOnce = function() {
    var c = this.getChildren().filter(function(e) { return e.enabled;});
    for(var i = 0; i < c.length; i++) {
        var ci = c[i].getChildren();
        var usePool = this.usePool || [];
        var idx = usePool.indexOf(ci[0]);
        if(idx > -1) {
            if(this.flashFunc && c[i].itemInfo) {
                this.flashFunc(ci[0],c[i].itemInfo);
            }
        }
    }
};

ccui.ListView.prototype.resetAllData = function(listData) {
    var c = this.getChildren();
    for(let index = 0; index< listData.length;index++){
        if(index >= c.length){
            this.insertGCItem(listData[index],0,true)
        }else{
            c[index].itemInfo = listData[index]
        }
    }

    if(listData.length < c.length){
        for(let index = c.length-1;index >= listData.length;index--){
            this.removeItemWithGC(index)
        }
        this.itemMaxindex = listData.length;
    }
    this.refreshOnce();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值