我们都知道gui中有许多的控件,所以为了使用更加完美,要进行监听各个GUI控件的交互事件。
cocos2d-x3.x开始,支持自有事件的控件都提供了addEventListener接口来设置各自的监听函数,并使用functional来接收监听函数。
以下以TextFiled为例说明:1.编辑器中设置交互或者程序中调用setTouchEnabled(true)
2.编写一个监听函数
void yourClass::textFieldEvent(Ref *pSender, TextField::EventType type){
switch (type) {
case TextField::EventType::ATTACH_WITH_IME:
CCLOG("获得输入焦点");
break;
case TextField::EventType::DETACH_WITH_IME:
CCLOG("失去输入焦点");
break;
case TextField::EventType::INSERT_TEXT:
CCLOG("输入了文本");
break;
case TextField::EventType::DELETE_BACKWARD:
CCLOG("删除了文字");
break;
default:
break;
}
}
3.设置监听:
yourTextField->addEventListener(CC_CALLBACK_2(yourClass::textFieldEvent, this));
------------------------------------------------------------------------------------------------------------------------------------------
各个控件支持的自有事件:(截止于3.3RC0)
输入框(ui::TextFiled)
enum class EventType
{
ATTACH_WITH_IME,//获得输入焦点
DETACH_WITH_IME,//失去输入焦点
INSERT_TEXT,//输入了文本
DELETE_BACKWARD,//删除了文字
};
复选框(ui::CheckBox)
enum class ui::CheckBox::EventType
{
SELECTED,//勾选了复选框
UNSELECTED//取消勾选了复选框
};
滑动条(ui::Slider)
enum class ui::Slider::EventType
{
ON_PERCENTAGE_CHANGED//百分比改变。
};
滚动层(ui::ScrollView)
enum class ui::ScrollView::EventType
{
SCROLL_TO_TOP,//滚动到顶时触发。
SCROLL_TO_BOTTOM,//滚动到底时触发
SCROLL_TO_LEFT,//滚动到左边缘时触发
SCROLL_TO_RIGHT,//滚动到右边缘时触发
SCROLLING,//滚动时触发
BOUNCE_TOP,//顶部回弹效果达到极限时触发
BOUNCE_BOTTOM,//底部回弹效果达到极限时触发
BOUNCE_LEFT,//左部回弹效果达到极限时触发
BOUNCE_RIGHT//右部回弹效果达到极限时触发
};
列表容器(ui::ListView)
enum class ui::ListView::EventType
{
ON_SELECTED_ITEM_START,//点中某个项
ON_SELECTED_ITEM_END//点中了某个项并抬起(没有发生滑动)
};
翻页容器(ui::PageView)
enum class EventType
{
TURNING//滚动到了页
};
-------------------------------------------------------------------------------------------------------------------------------------------------------
通用触摸事件:
其他所有Widget类型的节点都支持addTouchEventListener和addClickEventListener这两个接口。可以通过些接口来接收触摸事件。
addTouchEventListener的使用步骤如下:(c++下)
1.同样的准备好你的widget节点,在编辑器中开启交互(或在代码中setTouchEnabled(true))。
2.定义一个函数,形式如下
void ACuteClass::onTouchEvent(cocos2d::Ref *ref, Widget::TouchEventType touchType)
{
switch(touchType)
{
case Widget::TouchEventType::BEGAN:
CCLOG("on began");
break;
case Widget::TouchEventType::MOVED:
CCLOG("on moved");
break;
case Widget::TouchEventType::ENDED:
CCLOG("on ended");
break;
case Widget::TouchEventType::CANCELED:
CCLOG("on canceled");
break;
default:
CCLOG("impossible");
}
}
3.把这个函数传递给addTouchEventListener接口:
your_widget->addTouchEventListener(CC_CALLBACK_2(ACuteClass::onTouchEvent, this));//CC_CALLBACK_2照着写,表示有两个参数的回调。
addTouchEventListener的使用方法一样,不同的地方是:回调函数onTouchEvent在一次触摸中只回调一次,触发ENDED时回调。
-------------------------------------------------------------------------------------------------------------------------------------------------------
关于点击没响应的可能:
1.没开启交互。
2.控件被挡住。
(代码纯手打,有啥问题烦请指出啊)
-------------------------------------------------------------------------------------------------------------------------------------------------------
其他细节
1.如何获取触摸事件的坐标:
用下面这几个接口:
getTouchBeganPosition
getTouchMovePosition
getTouchEndPosition
2.关于ScrollView在某些情况下点到子控件不能拖动的问题
现在的Studio支持同时创建widget和非Widget类型的节点。这样会有一个问题。
Widget类型接受到触摸事件时,会把这些事件向上层传递,但是在遇到非Widget节点时会停下来。这会导致点击ScrollView等View类中的控件(两者之间有node)拖动时,拖动失败。
解决方案:
1.设置View中的控件的SwalloTouches属性为false。使控件不截断touch事件
2.或者改下源码:将如下代码替换掉Widget中同名函数。
void Widget::propagateTouchEvent(cocos2d::ui::Widget::TouchEventType event, cocos2d::ui::Widget *sender, cocos2d::Touch *touch)
{
Widget *widgetParent = nullptr;
for(Node *p = this;widgetParent == nullptr;)
{
p = p->getParent();
if(p)
{
widgetParent = dynamic_cast(p);
}
else
{
return;
}
}
widgetParent->interceptTouchEvent(event, sender, touch);
}
<span style="font-family: arial; font-size: 12px;"></span>