CocosCreator之PageView嵌套ScrollView的事件处理(二)

一、这段话可能有点长:

上篇里面讲了代码如何用代码控制scrollview和pageview的滚动、滑动、点击事件,但是有这么个美中不足的地方,就是左右滑动翻页的时候,如果按住不松,只要滑动超过一定距离,就会直接翻页。但是按照pageview原本的效果,在触摸事件没有结束的时候,是不会进行翻页操作的。
加上项目里有个这种的新需求,所以下边贴上实现过程,如有不足之处,请多多指教,互相学习。

二、原因

我们知道,在pageview的content里面的page添加了scrollview之后,会因为scrollview在上层,导致我们的触摸操作没法传达到pageview。所以我们要想办法让操作传达到pageview。

三、操作

  1. 新建一个脚本:testPageView.js(起名随意,不要在意这些细节哈哈)

  2. 我们重写creator源码里面的CCScrollView.js脚本的_hasNestedViewGroup方法(这里为什么重写的是scrollview的源码是因为pageview其实继承的就是scrollview,源码line:909)。
    原先的_hasNestedViewGroup方法如下:

//this is for nested scrollview
    _hasNestedViewGroup (event, captureListeners) {
        if (event.eventPhase !== cc.Event.CAPTURING_PHASE) return;

        if (captureListeners) {
            //captureListeners are arranged from child to parent
           for (let i = 0; i < captureListeners.length; ++i){
                let item = captureListeners[i];

                if (this.node === item) {
                    if (event.target.getComponent(cc.ViewGroup)) {
                        return true;
                    }
                    return false;
                }

                if(item.getComponent(cc.ViewGroup)) {
                    return true;
                }
            }
        }
        return false;
    },

重写的方法如下(重写的时候需要将脚本的expends:cc.Component改为cc.PageView):

_hasNestedViewGroup(event, captureListeners) {
    if (event.eventPhase !== cc.Event.CAPTURING_PHASE) return;
    if (!event.touch) return;
    
    const moveDelta = event.touch.getDelta();
    // TODO: 2.如果是上移移动则直接吞噬
    if (captureListeners) {
      for (let i = 0; i < captureListeners.length; ++i) {
        const item = captureListeners[i];
        if (item) {
          // 自身节点
          if (this.node === item) {
            if (moveDelta.y === 0) {
              return false;
            }
            //屏蔽掉此判断,会导致scrollview没有回弹效果
            // if (event.target.getComponent(cc.ViewGroup)) {
                // return true;
            // }
          }
          // 其他节点但有viewGroup
          if (item.getComponent(cc.ViewGroup)) {
            return false;
          }
        }
      }
    }
    return true;
  },

3.添加一个pageview,将原先自带的pageview组件Remove,手动添加刚才写的脚本testPageView.js,如下
CocosCreator之PageView嵌套ScrollView的事件处理(二)_第1张图片
这里需要手动将content拖进去,pageview部分就配置完成了;

  1. 制作page预制体:用于添加在pageview的content下作为page(本步略,就是简单的单色节点);

  2. 制作scrollview预制体(代码控制添加,所以做成预制体):
    CocosCreator之PageView嵌套ScrollView的事件处理(二)_第2张图片就是正常的列表容器,content里面手动添加了三张图,配置如下:
    CocosCreator之PageView嵌套ScrollView的事件处理(二)_第3张图片

  3. 给场景添加脚本,代码控制在pageview里面添加scrollview(手动加也行,反正只是测试~),此步略,for循环添加就可以;

四、见证奇迹的时刻来临了(多gif预警):

CocosCreator之PageView嵌套ScrollView的事件处理(二)_第4张图片
CocosCreator之PageView嵌套ScrollView的事件处理(二)_第5张图片
我们发现,可以上下竖向滚动,可以横向左右翻页,大功告成~啊哈哈哈哈嗝,就在我以为已经成功的时候,发现了一个问题,就是竖向滚动的时候,不会回弹,比如
CocosCreator之PageView嵌套ScrollView的事件处理(二)_第6张图片
触摸松开之后,列表并没有回弹至顶部,经测试,是重写了方法之后,触摸结束后经由scrollview的_onTouchEnded方法并没有进入回弹,但是触摸到scrollview可视部分(view)外的时候,会触发_onTouchCancelled方法调用回弹。细心的大概已经注意到了,重写的方法里面有一行注释:“//屏蔽掉此判断,会导致scrollview没有回弹效果”,没错,把下面的判断的注释解开,你就会发现,竟然可以回弹了,神奇。效果如下
CocosCreator之PageView嵌套ScrollView的事件处理(二)_第7张图片
以上,就是pageview和scrollview嵌套时两者事件处理的方法,遗留问题就是现在两者的事件可以同时调用而不是一方调用的时候禁用掉另一方,还在发掘中,以后有需要了可能会不定期更新。

此致

敬礼

你可能感兴趣的:(CocosCreator之PageView嵌套ScrollView的事件处理(二))