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/

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...