代码拉取完成,页面将自动刷新
ScrollView/PageView嵌套方案。
基于CocosCreator2.4.x
看一下源码就会发现每一个处理触摸(滚轮的就不管了)的函数最开始都有这两行
_onTouchBegan(event, captureListeners) {
if (!this.enabledInHierarchy) return;
if (this._hasNestedViewGroup(event, captureListeners)) return;
...
}
不能嵌套的原因就在这个_hasNestedViewGroup函数里面
...
if (event.target.getComponent(cc.ViewGroup)) {
return true;
}
...
这个时候大部分小伙伴的做法可能都是继承ScrollView或PageView,然后重写一部分方法来解决嵌套的问题。
但是我们这里尝试换一个角度,比如我们手动发射一个假事件,让它不会被_hasNestedViewGroup过滤掉,并且我们的目标是让它成为一个单独的组件。
代码不多,直接上源码(新鲜出炉,未测BUG)
demo项目地址: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;
// 问:这里为啥不直接dispatchEvent
// 答:必须让ScrollView把真的event先消耗掉,我们再发射假的才可以,
// 可以去CCNode.js下找一个_doDispatchEvent函数,里面用到了_cachedArray这么个全局变量,
// 先发射假的话,真的那个数据就被清空了
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;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。