使用的编辑器与代码库:Cocos 2.1, 2.2 cocos2d-x 3.4, 3.5
抛砖引玉,仅提供思路,并非代表适合所有可能的其他UI制作方法或其他程序处理方案
问题重现:
编辑器制作界面Page1.csd,内有一个列表容器ListView;
编辑器制作子界面Widget1.csd,内有一些有交互性的控件、例如按钮;
程序运行时对Page1的ListView进行push了多个Widget1子界面;
问题现象:
拖动touch若位于Widget1的交互性的控件、例如按钮上时,无法正常滚动滑动列表容器ListView
解决方案 一:
修改代码,Widget::interceptTouchEvent, Widget::interceptTouchEvent 两个函数,
cocos2d-x\cocos\ui\UIWidget.cpp
void Widget::propagateTouchEvent(cocos2d::ui::Widget::TouchEventType event, cocos2d::ui::Widget *sender, cocos2d::Touch *touch)
{
#if CC_MOD_DONEYKOO // mod by doneykoo
// note that Widget::interceptTouchEvent() is different than this->interceptTouchEvent() if subclass overrides
Widget::interceptTouchEvent(event, sender, touch);
#else // cocos2d-x original
Widget* widgetParent = getWidgetParent();
if (widgetParent)
{
widgetParent->interceptTouchEvent(event, sender, touch);
}
#endif
}
void Widget::interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event, cocos2d::ui::Widget *sender, Touch touch)
{
Widget widgetParent = getWidgetParent();
if (widgetParent)
{
widgetParent->interceptTouchEvent(event,sender,touch);
}
#if CC_MOD_DONEYKOO // mod by doneykoo
if (!widgetParent && this->getParent())
{
int maxDepth = 9;
int depth = 1;
// nodeP means Parent
// nodePofP means Parent of Parent
auto nodeP = this->getParent();
auto nodePofP = nodeP->getParent();
while (nodeP && nodePofP)
{
Widget* widgetPofP = nodePofP ? dynamic_cast<Widget*>(nodePofP) : nullptr;
if (widgetPofP)
{
widgetPofP->interceptTouchEvent(event,sender,touch);
break;
}
else
{
++depth;
if (depth > maxDepth)
{
break;
}
nodeP = nodePofP;
nodePofP = nodeP->getParent();
}
}
}
#endif
}
解决方案 二:
虽然比较粗暴,但能解决所有潜在的由于根节点是普通Node*而导致的与cocos2d:ui的冲突问题 ,
(例如同时解决在上述问题重现前提下ListView中点击某个widget后getCurSelectedIndex()得到的总是第一个widget的问题)
cocos2d-x\cocos\editor-support\cocostudio\WidgetReader\NodeReader\NodeReader.cpp
Node* NodeReader::createNodeWithFlatBuffers(const flatbuffers::Table *nodeOptions)
{
#if CC_MOD_DONEYKOO // mod by doneykoo
// note that Widget::interceptTouchEvent() is different than this->interceptTouchEvent() if subclass overrides
ui::Widget* widget = ui::Widget::create();
Node* node = widget;
#else // cocos2d-x original
Node* node = Node::create();
#endif
setPropsWithFlatBuffers(node, nodeOptions);
return node;
}