解决编辑器制作的界面中列表容器ListView翻页容器PageView内add子界面后滚动拖动响应问题

使用的编辑器与代码库: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;
}

@东扬冬阳 (额 这个帖子内@功能有效吗?)

@ 貌似不起作用,编辑了

纯手写没这种问题,怎么解决!!!

标记一下,太好了。

好牛逼的样子,虽然看不懂…