关于 ScrollView的嵌套问题和想法

使用场景

很多同学觉得没有使用场景,这边列一个使用场景出来。

原型解释

  • 这个是一个游戏任务的原型
  • P1横向PageView 有多种任务使用P1进行任务类型切换
  • L2纵向ScrollView,列出了多个条目
  • L3横向ScrollView,列出了多个物品奖励,奖励图标可点击看物品详情
  • 去完成是一个按钮,点击后可以跳到相关的游戏玩法中

操作需求

  • 按住去完成,上下滑则取消按钮点击状态,同时L2能上下滑;
  • 按住去完成,左右滑则取消按钮点击状态,同时P1能左右滑;
  • 按住L3中的奖励图标,左右滑则取消按钮图标状态,同时L3能左右滑;
  • 按住L3中的奖励图标,上下滑则取消按钮图标状态,同时L2能上下滑;

滑动限制

  • P1,L2,L3,同时只有一个能滑动
  • L2上下滑动时,左右滑不能触发P1的左右滑
  • L3 左右滑时,P1不能左右滑,且L2不能上下滑

目前的问题

以上的需求在目前 Creator 的ScrollView及PageView中是不能实现的,除非自己去用Mask+Touch完全自己重写一套操作

实现想法

  1. Touch 行为,增加增加一个 CannelOnTouchMove的属性 (在按下后,触摸点移动超过一定距离,取消点击事件)
    • 可用于列表或是可滑动组件内部的按钮使用,例如去完成按钮,及奖励图标的实现
  2. ScrollView 需要去掉 CancelInnerTouchEvent 的实现,事件自内而外
  3. ScrollView 需要增加一个属性:滑动与方向一致时才触发;只在组件设置了方向时才生效
  4. 多级 ScrollView 向外传递Touch事件时,需要增加限制
  • 子ScrollView在TouchBegan里,如果外层ScrollView方向不一样,则向上传递
  • 子ScrollView在TouchBegan里,如果外层ScrollView方向一样,则阻止向上传递
  • 根据这个规则,ScrollView的TouchBegan,最多向外传递一次给外层ScrollView

想讨论下实际可行的方案

可以让策划改成选项卡,点击选项卡切换不同的类别分页

每日任务,主线任务,支线任务。。。

兄弟,你抢了策划的妹子了吧

至少要在 touchmove 里面才能判断方向,而且这个方向需要根据手感来调节,比如45度滑动,上下滑动还是左右滑动? 我来做的话,会在creator控件的基础上 取消 scrollview 的触摸事件、按钮改为sprite, 然后自己 node.on 触摸事件,在触摸事件回调里来决定滑动哪个控件、方向、是否点击按钮。

你看这样行不行:
1 、不要使用PageView
2、只使用ScrollView
3、3个SV并排放
4、用Mask或者直接只显示当前页
5、检测触摸结束时的滑动距离来实现胡奥的那个效果。

ScrollView里,move时可以在一定的距离内,不去真正滑动,正如按钮一样,按下去,滑动小于一定距离不会取消按下状态一样
现在ScrollView里的取消子结点点击事件的实现,也是在 touchMove里实现的

_onTouchMoved: function(event, captureListeners) {
		// 省略 .....

        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);
    },

硬写总能做到这个效果,但是考虑来,这些其实应该是 ScrollView系组件,应该要支持的才对。

主要是想从组件层面来解决这个需求,嵌套组件这个需求在游戏里,还是经常有的,上面这个例子相对会极端一些

已实现了 两个ScrollView的嵌套。 Pageview是继承的ScrollView, 差不多一样的,参考一下,希望能帮到你。

https://github.com/NRatel/CCCNestableScrollView

1赞