在PageView里面包含ScrollView的问题

PageView是横向左右滚动,里面的ScrollView是纵向滚动的,现在里面的ScrollView会挡住外层PageView的左右滚动消息,期望是,ScrollView可以上下滚动,外层的PageView同时可以左右滚动.怎么实现?感觉是把消息传递一下就行了.

论坛搜了一圈,提这个类似问题的人很多,基本都没人回答.:sweat:

还是没人回复啊.

因为上层的触摸吞噬了下层的,所以只有上层的能动,我在论坛里看过,说是好像暂时没办法解决,你可以试试自己模拟listview写在里面看看

其实完全是纵向的ScrollView不应该吞噬横向的消息,这个实现改一改感觉不难

这个功能大概要自己写了,ui命名控件下的控件有一套向父节点传递事件的机制,改写之

那只有自己动手改了,唉

其实改起来还行, 我就改了pageview,加了滑动开始、停止和翻页失败停止的事件,原本只有一个翻页完成的事件

我觉得可能是改ScrollView呢,只要不吞噬消息就行.

ScrollView的这几个消息:
this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchBegan, this, true);
this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this, true);
this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this, true);
this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancelled, this, true);
this.node.on(cc.Node.EventType.MOUSE_WHEEL, this._onMouseWheel, this, true);

在里面把

if (this._touchMoved) {
event.stopPropagation();
} else {
this._stopPropagationIfTargetIsMe(event);
}

类似这种stopPropagation的玩意处理一下应该就可以了.

刚试了这方案不行

cc.Class({
extends: cc.ScrollView,

//private methods
_registerEvent: function () {
    this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchBegan, this, true);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this, true);
    this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this, true);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancelled, this, true);
    this.node.on(cc.Node.EventType.MOUSE_WHEEL, this._onMouseWheel, this, true);
},

_unregisterEvent: function () {
    this.node.off(cc.Node.EventType.TOUCH_START, this._onTouchBegan, this, true);
    this.node.off(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this, true);
    this.node.off(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this, true);
    this.node.off(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancelled, this, true);
    this.node.off(cc.Node.EventType.MOUSE_WHEEL, this._onMouseWheel, this, true);
},

// touch event handler
_onTouchBegan: function(event, captureListeners) {
    if (!this.enabledInHierarchy) return;
    if (this._hasNestedViewGroup(event, captureListeners)) return;

    var touch = event.touch;
    if (this.content) {
        this._handlePressLogic(touch);
    }
    this._touchMoved = false;
    //this._stopPropagationIfTargetIsMe(event);
},

_onTouchMoved: function(event, captureListeners) {
    if (!this.enabledInHierarchy) return;
    if (this._hasNestedViewGroup(event, captureListeners)) return;

    var touch = event.touch;
    if (this.content) {
        this._handleMoveLogic(touch);
    }
    // Do not prevent touch events in inner nodes
    if (!this.cancelInnerEvents) {
        return;
    }

    var deltaMove = cc.pSub(touch.getLocation(), touch.getStartLocation());
    //FIXME: touch move delta should be calculated by DPI.
    if (cc.pLength(deltaMove) > 7) {
        if (!this._touchMoved && event.target !== this.node) {
            // Simulate touch cancel for target node
            var cancelEvent = new cc.Event.EventTouch(event.getTouches(), event.bubbles);
            cancelEvent.type = cc.Node.EventType.TOUCH_CANCEL;
            cancelEvent.touch = event.touch;
            cancelEvent.simulate = true;
            event.target.dispatchEvent(cancelEvent);
            this._touchMoved = true;
        }
    }
    //this._stopPropagationIfTargetIsMe(event);
},

_onTouchEnded: function(event, captureListeners) {
    if (!this.enabledInHierarchy) return;
    if (this._hasNestedViewGroup(event, captureListeners)) return;

    this._dispatchEvent('touch-up');

    var touch = event.touch;
    if (this.content) {
        this._handleReleaseLogic(touch);
    }
    //if (this._touchMoved) {
    //    event.stopPropagation();
    //} else {
    //    this._stopPropagationIfTargetIsMe(event);
    //}
},
_onTouchCancelled: function(event, captureListeners) {
    if (!this.enabledInHierarchy) return;
    if (this._hasNestedViewGroup(event, captureListeners)) return;

    // Filte touch cancel event send from self
    if (!event.simulate) {
        var touch = event.touch;
        if(this.content){
            this._handleReleaseLogic(touch);
        }
    }
    //this._stopPropagationIfTargetIsMe(event);
},

_onMouseWheel: function(event, captureListeners) {
    if (!this.enabledInHierarchy) return;
    if (this._hasNestedViewGroup(event, captureListeners)) return;

    var deltaMove = cc.p(0, 0);
    var wheelPrecision = -0.1;
    if(CC_JSB) {
        wheelPrecision = -7;
    }
    if(this.vertical) {
        deltaMove = cc.p(0, event.getScrollY() * wheelPrecision);
    }
    else if(this.horizontal) {
        deltaMove = cc.p(event.getScrollY() * wheelPrecision, 0);
    }

    this._mouseWheelEventElapsedTime = 0;
    this._processDeltaMove(deltaMove);

    if(!this._stopMouseWheel) {
        this._handlePressLogic();
        this.schedule(this._checkMouseWheel, 1.0 / 60);
        this._stopMouseWheel = true;
    }

    //this._stopPropagationIfTargetIsMe(event);
},

});

这样改为什么不行,求老板解答.@Jare@Panda

这个问题老早也查过,网上没有解决方案,只有屏蔽了scrllow的所有事件,自定义事件触发处理,但问题在于需要自己计算的横向滚动左右翻页会比较迟钝:sweat:

已经解决了,方案如下:

cc.Class({
extends: cc.ScrollView,

//private methods
_registerEvent: function () {
    this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchBegan, this, false);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this, false);
    this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this, false);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancelled, this, false);
    this.node.on(cc.Node.EventType.MOUSE_WHEEL, this._onMouseWheel, this, false);
},

_unregisterEvent: function () {
    this.node.off(cc.Node.EventType.TOUCH_START, this._onTouchBegan, this, false);
    this.node.off(cc.Node.EventType.TOUCH_MOVE, this._onTouchMoved, this, false);
    this.node.off(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this, false);
    this.node.off(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancelled, this, false);
    this.node.off(cc.Node.EventType.MOUSE_WHEEL, this._onMouseWheel, this, false);
},

});

这个方案有个问题,点在非内部控件区又不行.

http://forum.cocos.com/t/pageview-scrowview/44922/7,官方说重写_hasNestedViewGroup这个来处理

上面的链接是我问的,可惜我不明白南大的方法如何实现,有做过的分享一下。

_hasNestedViewGroup: function (event, captureListeners) {
if(this.node === item) {
var py= Math.abs(event.currentTouch.prevPoint.y-event.currentTouch.startPoint.y);
var px = Math.abs(event.currentTouch.prevPoint.x-event.currentTouch.startPoint.x);
if(py<px)
{
return false;
}
}
我这样处理了下可以上下左右滑动,不过调用pageview的api就失效了

这个是修改哪个位置的哪个文件?怎样编译才生效?

你这个不管用