1 Star 0 Fork 15

lehung / ScrollViewNesting

forked from 向前 / ScrollViewNesting 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

ScrollView/PageView nesting scheme.

Based on CocosCreator2.4.x

Recently, I have found a lot of friends in groups and forums who need ScrollView/PageView nesting, but Creator does not support it by default. We try to solve it.

1. Analyze the reasons


If you look at the source code, you will find that every function that handles touch (ignoring the wheel) has these two lines at the beginning.

_onTouchBegan(event, captureListeners) {
     if (!this.enabledInHierarchy) return;
     if (this._hasNestedViewGroup(event, captureListeners)) return;
     ...
}

The reason why nesting cannot be done lies in the _hasNestedViewGroup function

...
if (event.target.getComponent(cc.ViewGroup)) {
     return true;
}
...

2. Solve the problem


At this time, most friends may inherit ScrollView or PageView, and then rewrite some methods to solve the nesting problem.

But let's try a different angle here. For example, we manually emit a fake event so that it will not be filtered out by _hasNestedViewGroup, and our goal is to make it a separate component.


There is not much code, just upload the source code (freshly released, no bugs tested)

Demo project address: https://gitee.com/cocos2d-zp/scrollview-nesting

const { ccclass, property } = cc._decorator;

interface EventTouch extends cc.Event.EventTouch {
     simulate?: boolean
     sham?: boolean
}

@ccclass
export default class ViewGroupNesting extends cc.Component {
     private events: EventTouch[] = [];

     onLoad() {
         this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchHandle, this, true);
         this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchHandle, this, true);
         this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchHandle, this, true);
         this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchHandle, this, true);
     }

     private onTouchHandle(event: EventTouch) {
         if (event.sham || event.simulate || event.target === this.node) return;

         const cancelEvent: EventTouch = new cc.Event.EventTouch(event.getTouches(), event.bubbles);
         cancelEvent.type = event.type;
         cancelEvent.touch = event.touch;
         cancelEvent.sham = true;
         // Question: Why not dispatchEvent directly here?
         // Answer: The ScrollView must consume the real event first, and then we can launch the fake one.
         // You can go to CCNode.js to find a _doDispatchEvent function, which uses a global variable like _cachedArray.
         // If the false is emitted first, the true data will be cleared.
         this.events.push(cancelEvent);
     }

     update() {
         if (this.events.length === 0) return;
         for (let index = 0; index < this.events.length; index++) {
             this.node.dispatchEvent(this.events[index]);
         }
         this.events.length = 0;
     }
}

空文件

简介

ScrollView/PageView nested demo 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/lehung/scrollview-nesting.git
git@gitee.com:lehung/scrollview-nesting.git
lehung
scrollview-nesting
ScrollViewNesting
master

搜索帮助