Laya經(jīng)驗(yàn)雜談:List控件通過Box Render實(shí)現(xiàn)渲染的注意事項(xiàng)

LayaAir IDE版本和庫版本: 1.8.0

Laya的ui控件list的渲染有兩種常見的實(shí)現(xiàn)方式。

  1. 通過itemRender實(shí)現(xiàn):
    • list.itemRender賦值一個(gè)實(shí)現(xiàn)了dataSource接口的類定義;
    • 通過list.array傳入數(shù)據(jù)源;
  2. 通過renderHandler實(shí)現(xiàn):
    • LayaAir IDE的編輯模式下給List控件添加Box控件作為其子級(jí)容器;
    • 將該Box控件的renderType屬性設(shè)置為render;
    • list.renderHandler賦值一個(gè)Handler對(duì)象;
    • 通過list.array傳入數(shù)據(jù)源;

不過本文只探討使用第2種實(shí)現(xiàn)方式需要注意的地方。

通過renderHandler實(shí)現(xiàn)渲染時(shí),box與dataSource遵循“有則賦值”規(guī)則

什么是“有則賦值”?說人話就是,通過dataSource傳入的數(shù)據(jù)對(duì)象與box存在共有的屬性(名字相同的屬性)時(shí),將會(huì)把數(shù)據(jù)對(duì)象的值賦給box。邏輯類似于:

if(data.hasOwnProperty('name') && box.hasOwnProperty('name')){
    box.name = data.name;
}

下面通過一個(gè)例子來說明,以下是一個(gè)將動(dòng)物信息展示出來的list實(shí)現(xiàn):

import WebGL = Laya.WebGL;
// 程序入口
class GameMain{
    constructor()
    {
        Laya.init(400,600, WebGL);
        Laya.stage.bgColor = '#FFFFFF';

        Laya.loader.load('res/atlas/comp.atlas', Laya.Handler.create(this, ()=>{
            const data:{name:string, weight:number, src:string}[] = [];
            data.push({name:'小狗', weight:5, src:'dog.png'});
            data.push({name:'小貓', weight:3, src:'cat.png'});
            data.push({name:'小鳥', weight:0.2, src:'bird.png'});
            data.push({name:'小雞', weight:0.5, src:'chick.png'});
            data.push({name:'小豬', weight:10, src:'pig.png'});
            const view:ui.ListViewUI = new ui.ListViewUI();
            view.pos(50,50);
            view.listDemo.array = data;
            Laya.stage.addChild(view);

            view.listDemo.renderHandler = Laya.Handler.create(this, (itemRender:Laya.Box, index:number)=>{
                const label:Laya.Label = itemRender.getChildByName('lblContent') as Laya.Label;
                const d = data[index];
                label.changeText(d.name + ' 重量:' + d.weight + ' 圖像:' + d.src);
            }, undefined, false);

        }))
    }
}
new GameMain();

運(yùn)行效果如下圖:


符合預(yù)期的表現(xiàn)

目前表現(xiàn)跟預(yù)期還是一致的,接下來,假設(shè)每種動(dòng)物的圖片資源尺寸不一,并且怪物形象在圖片中的實(shí)際位置也不統(tǒng)一。我們需要增加pivotXpivotY的配置,來統(tǒng)一怪物形象的實(shí)際顯示位置。我們對(duì)以上代碼做如下的修改:

import WebGL = Laya.WebGL;
// 程序入口
class GameMain{
    constructor()
    {
        Laya.init(400,600, WebGL);
        Laya.stage.bgColor = '#FFFFFF';

        Laya.loader.load('res/atlas/comp.atlas', Laya.Handler.create(this, ()=>{
            // 僅對(duì)數(shù)據(jù)源做了修改,增加了pivotX和pivotY屬性
            const data:{name:string, weight:number, src:string, pivotX:number, pivotY:number}[] = [];
            data.push({name:'小狗', weight:5, src:'dog.png', pivotX:0, pivotY:0});
            data.push({name:'小貓', weight:3, src:'cat.png', pivotX:20, pivotY:0});
            data.push({name:'小鳥', weight:0.2, src:'bird.png', pivotX:0, pivotY:0});
            data.push({name:'小雞', weight:0.5, src:'chick.png', pivotX:-20, pivotY:0});
            data.push({name:'小豬', weight:10, src:'pig.png', pivotX:0, pivotY:0});

            view.pos(50,50);
            view.listDemo.array = data;
            Laya.stage.addChild(view);

            view.listDemo.renderHandler = Laya.Handler.create(this, (itemRender:Laya.Box, index:number)=>{
                const label:Laya.Label = itemRender.getChildByName('lblContent') as Laya.Label;
                const d = data[index];
                label.changeText(d.name + ' 重量:' + d.weight + ' 圖像:' + d.src);
            }, undefined, false);

        }))
    }
}
new GameMain();

運(yùn)行效果如下圖:


不符合預(yù)期的表現(xiàn)

我的天!剛才一切正常的表現(xiàn),居然發(fā)生了異常,list的渲染出來的item錯(cuò)位了。其實(shí)這里就是上文說的“有則賦值”的規(guī)則,我們實(shí)際并沒有預(yù)期要把dataSourcepivotXpivotY賦值給box,但實(shí)際卻發(fā)生了。

我們可以把數(shù)據(jù)源里的pivotXpivotY修改為srcPivotXsrcPivotY來避免上述意外的發(fā)生,我真是個(gè)小機(jī)靈鬼。(也可以通過其他方式避免,本文不贅述)

data.push({name:'小狗', weight:5, src:'dog.png', srcPivotX:0, srcPivotY:0});

總結(jié):通過renderHandler實(shí)現(xiàn)list渲染的時(shí)候,千萬要注意共有屬性的非預(yù)期賦值。

引申:發(fā)生上述“有則賦值”的地方在LayaBox控件,其有一接口為dataSource來接收數(shù)據(jù)源,可以在laya.ui.js找到以下代碼,有興趣的同學(xué)可以斷點(diǎn)調(diào)試加深了解,這里也不詳述了:

/**
*<code>Box</code> 類是一個(gè)控件容器類。
*/
//class laya.ui.Box extends laya.ui.Component
var Box=(function(_super){
    function Box(){
        Box.__super.call(this);;
    }

    __class(Box,'laya.ui.Box',_super);
    var __proto=Box.prototype;
    Laya.imps(__proto,{"laya.ui.IBox":true})
    /**@inheritDoc */
    __getset(0,__proto,'dataSource',_super.prototype._$get_dataSource,function(value){
        this._dataSource=value;
        for (var name in value){
            var comp=this.getChildByName(name);
            if (comp)comp.dataSource=value[name];
            else if (this.hasOwnProperty(name)&& !((typeof (this[name])=='function')))this[name]=value[name];
        }
    });

    return Box;
})(Component)
最后編輯于
?著作權(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)容

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