Quick-x UI容器项拷贝

Quick-x中,ListView:pushBackCustomItem()以及Widget:Clone(),均会导致模板控件中事先保存的自定义属性消失。这使得我们要每次克隆时需重新获取子控件引用。本文提供一个解决方案。

问题描述
使用ListView时,通常有两个部分,一个是List容器本身,另一个是子项模板Templete。Templete上有一些控件与数据相关联,比如背包物品的图标(ImageView)、数量(Label)等。下面以clone方案为例,假设有一个面板PanelBag.json,它里面有一个名为lstItem的ListView;另外有一个背包项widgetItem.json,它里面有一个lbName的Label用于标识物件名称。
理想的写法
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

function PanelBag:initialize()

    self._widget = GUIReader:shareReader():widgetFromJsonFile("res/PanelBag.json")

    self._lstItem = self._widget:getChildByName("lstItem")

    self:addWidget(self._widget)

 

    self._tplItem = GUIReader:shareReader():widgetFromJsonFile("res/widgetItem.json")

    self._tplTest._lbName = self._tplTest:getChildByName("lbName")

 

    self:addTest("one")

    self:addTest("two")

    self:addTest("three")

end

 

function PanelBag:addItem(name)

    local widgetItem = self._tplItem:clone()

    widgetItem._lbName:setText(name)                 -- nil错误,_lbName引用丢失

    self._lstItem:pushBackCustomItem(widgetItem)

end



改进
如果在clone之后重新用getChildByName获取一次子控件,一旦Item项变得多,并且子控件更加复杂时,瞬间速度受收到影响。下面是改进方案。

1

2

3

4

5

6

7

8

function PanelBag:addItem(name)

    local widgetItem = self._tplItem:clone()    -- 拷贝C++数据

    local peer = tolua.getpeer(self._tplItem)   -- 拷贝peertable

    tolua.setpeer(widgetItem, peer)

 

    widgetItem._lbName:setText(name)             -- _lbName已经可以访问了

    self._lstTest:pushBackCustomItem(widgetItem)

end





原理
C++函数Widget::clone()的返回值是一个usertype,lua中对ussertype的扩展通过peertable实现。也就是说clone调用后,我们获得的是_tplTest丢弃了peertable的干净拷贝,这也是_lbName引用丢失的原因。那么只需将_tplTest的peertable赋予新的widgetItem就可以还原引用。

优点
避免反复加载文件或缓存文件
避免较缓慢的json文件到控件的解析
不用为每个拷贝项调用getChild()子级查找了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值