1.我用最新的2.3的cocostudio摆了个简单的界面:
继承关系(名字比较乱没改):
2.在cocos2dx lua程序中使用
【加载界面】
用cocostudio导出为csb文件,放到资源目录去,添加该ui代码如下:
-- load csb local node = cc.CSLoader:createNode('Test.csb') layer:addChild(node)
【按钮Button】
cocos3.x的版本比较强调用事件来传递消息,减少模块间的耦合。这里gui的处理也基本时给要处理的控件添加事件侦听。
-- btn local btn = node:getChildByName('btn_ok') btn:addTouchEventListener(function(sender,state) -- 2 if state == ccui.TouchEventType.ended then print('on btn ok') end end)
【进度条LoadingBar和复选框CheckBox】
-- loading bar local loading = node:getChildByName('LoadingBar_1') -- checkBox local chk = node:getChildByName('CheckBox_1') chk:addEventListener(function (sender,type) -- 0 if type == ccui.CheckBoxEventType.selected then -- sel print('sel') loading:setPercent(50) else -- unsel print('unsel') loading:setPercent(0) end end)
【列表控件ListView】
容器有好几个,ScrollView和PageView都比较容易,这里说下ListView。
ListView可以设置列表项的模型,设置了后可以轻松的克隆多个。他的用处就是美术可以在编辑器里把模板编辑好,程序拿来克隆就行了。如果有多种类型,美术就多摆几个,程序搭框架的时候封装一层设置模型的逻辑来选择用哪个模板,这样也可以实现不同的列表项。具体后面有空可以写些例子。
下面设置模板并创建多个:
-- set item model local item = list:getChildByName('Image_item') list:setItemModel(item) list:removeAllChildren() for i = 1,10 do list:pushBackDefaultItem() end我这里的模板是在编辑器里放在listview下的,设置完就移除了(注意移除要用listview来remove,不要removeFromParent)。此时的运行效果如下:
下面我们想要相应按钮按下:
list:addEventListener(function (sender,type) -- 0 if type == ccui.ListViewEventType.ONSELECTEDITEM_START then -- sel print("select child index = ",sender:getCurSelectedIndex()) loading:setPercent(50) else -- unsel print('unsel') loading:setPercent(0) end end)当按钮刚按下(其实是其touchBegan的时候)的时候是start事件,抬起的时候(即touchEnded)是end事件。这时你会问为何添加的是list的事件,却能在按钮按下的时候收到消息。这是因为他们的基类Widget和ListView做了一些事情。
Widget会在touchBegan之类的触摸处理里向父亲传递该事件:
bool Widget::onTouchBegan(Touch *touch,Event *unusedEvent) { _hitted = false; if (isVisible() && isEnabled() && isAncestorsEnabled() && isAncestorsVisible(this) ) { _touchBeganPosition = touch->getLocation(); if(hitTest(_touchBeganPosition) && isClippingParentContainsPoint(_touchBeganPosition)) { _hitted = true; } } if (!_hitted) { return false; } setHighlighted(true); /* * Propagate touch events to its parents */ if (_propagateTouchEvents) { this->propagateTouchEvent(TouchEventType::BEGAN,this,touch); } pushDownEvent(); return true; } void Widget::interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event,cocos2d::ui::Widget *sender,Touch *touch) { Widget* widgetParent = getWidgetParent(); if (widgetParent) { widgetParent->interceptTouchEvent(event,sender,touch); } }这样当一个widget被触摸的时候,他的祖先们都会(有机会)得知他的某个后辈被触摸了。所以这里按钮按下时,listview能收到该事件并处理:
void ListView::interceptTouchEvent(TouchEventType event,Widget *sender,Touch* touch) { ScrollView::interceptTouchEvent(event,touch); if (event != TouchEventType::MOVED) { Widget* parent = sender; while (parent) { if (parent && parent->getParent() == _innerContainer) { _curSelectedIndex = getIndex(parent); break; } parent = dynamic_cast<Widget*>(parent->getParent()); } if (sender->isHighlighted()) { selectedItemEvent(event); } } } void ListView::selectedItemEvent(TouchEventType event) { this->retain(); switch (event) { case TouchEventType::BEGAN: { if (_listViewEventListener && _listViewEventSelector) { (_listViewEventListener->*_listViewEventSelector)(this,LISTVIEW_ONSELECTEDITEM_START); } if (_eventCallback) { _eventCallback(this,EventType::ON_SELECTED_ITEM_START); } if (_ccEventCallback) { _ccEventCallback(this,static_cast<int>(EventType::ON_SELECTED_ITEM_START)); } } break; default: { if (_listViewEventListener && _listViewEventSelector) { (_listViewEventListener->*_listViewEventSelector)(this,LISTVIEW_ONSELECTEDITEM_END); } if (_eventCallback) { _eventCallback(this,EventType::ON_SELECTED_ITEM_END); } if (_ccEventCallback) { _ccEventCallback(this,static_cast<int>(EventType::ON_SELECTED_ITEM_END)); } } break; } this->release(); }这样的结果就是只要某个item下的某个按钮被触摸了listview就会收到,所以问题也来了,如果有多个按钮怎么办?上面listview的事件参数只有this(是listview指针)和事件类型,没法知道是哪个按钮被按下了。通过curSel只能得知是哪个item被按下了,需要区分是item下的哪个按钮被按下了,则最好给按钮添加事件处理。
你担心按钮多懒得添加,那么我们就使用模板呗,给模板加事件处理,通过模板克隆的列表项也会有该处理的。将下面这段lua代码添加到设置模板之前:
-- set item callback: we can just add event to model,and diff from curSel local item0 = list:getItem(0) local btn_0 = item0:getChildByName('Button_2') btn_0:addTouchEventListener(function(sender,state) if state == 2 then print('on btn test 0') end end)这样就能给每个列表项的按钮添加事件并响应了。所以listview的触摸事件只能用于1个按钮的情况吧(不知后面是否会在事件里加入按钮的参数),多个按钮的话给模板里的该按钮加就行。