Quick-Cocos2d-x UI容器项拷贝

Quick-Cocos2d-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()子级查找了


来源网址:http://www.lolofinil.com/2014/07/22/quickx_widget_ext_clone/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值