Quick-Cocos2d-x UI容器项拷贝

前端之家收集整理的这篇文章主要介绍了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
functionPanelBag: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
functionPanelBag:addItem(name)
localwidgetItem=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
functionPanelBag:addItem(name)
localwidgetItem=self._tplItem:clone()--拷贝C++数据
localpeer=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/

猜你在找的Cocos2d-x相关文章