如果孩子返回false,让父视图假定MotionEvents [英] Let parent View assume MotionEvents if child returns false

查看:216
本文介绍了如果孩子返回false,让父视图假定MotionEvents的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序需要以不寻常的方式进行事件处理。

I have a application that need event handling on a unusual way.

对于我的问题,让我先解释一个简单的例子,即Android的当前事件处理系统不适合我。

For my question, let me first explain a simple case that the current event handling system of Android don't fits for me.

假设我有一个FrameLayout(从现在开始我将调用ViewSwiper),添加的所有视图都是MATCH_PARENT X MATCH_PARENT(that我会调用PageView),它通过翻译实际的视图来处理事件,并根据移动的方向进行替换。
此组件已经完成并正常工作(使用动画来滑动视图)。

Supposing that I have a FrameLayout (that I'll call ViewSwiper since now) that all Views added on it are MATCH_PARENT X MATCH_PARENT (that I'll call PageView), it's handles events by translating the actual View and replace it based on the direction of moving. This component I already have done and work properly ( Using Animation to swipe views ).

但是,该问题是在它上面添加的PageView,如果ImageViews在onTouchEvent上返回false,则ViewSwiper将处理事件,让另一个PageView进入屏幕,但是如果我在其上添加了一个ScrollView,则所有的事件将被Scroll使用,ViewSwiper将无法替换PageView。

But the problem is on that PageView I add on top of it, in case of ImageViews that return false on it's onTouchEvent, the ViewSwiper will handle the events and let another PageView enter the screen, but if I add a ScrollView on that, all the events will be consumed by the Scroll and the ViewSwiper will not have chance to replace the PageView.

所以我发现,返回的ScrollView的false onTouchEvent,父级可以假设它是事件,我写了这个ScrollView子类来测试它:

So I figured out that returning false onTouchEvent of the ScrollView the parent can assume it's events, I wrote this sub-class of ScrollView to test it:

public class ScrollViewVertical extends ScrollView {
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        super.onTouchEvent(evt);
        return false;
    }
}

但返回false会使任何进一步的事件发送到父母,但我需要这些事件为VERTICAL滚动,所以我有想法只有当用户正在移动HORIZONTAL时才返回错误,这就是我的代码如下:

But returning false make any further events to get dispatched to the parent, but I need these events for VERTICAL scrolling, so I have the idea to return falses only if the user are moving HORIZONTAL, that's what my code looks like:

public class ScrollViewVertical extends ScrollView {
    private MovementTracker moveTracker;
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
        moveTracker = new MovementTracker();
    }
    public boolean onTouchEvent(MotionEvent evt) {
        if (moveTracker.track(evt))
            if (moveTracker.getDirection() == Direction.HORIZONTAL)
                return false;

        return super.onTouchEvent(evt);
    }
}

PS:MovementTracker将在track()之后返回true一些事件,并说明用户正在移动的方向。

PS: MovementTracker will returns true on track() after some events and tell on which direction the user is moving.

但是在这种情况下,ScrollView会继续接收事件,因为它在第一个事件上返回true。

But in that case, the ScrollView keep receiving events since it's returns true on the first events.

任何有关如何在孩子返回false时处理ViewSwiper上的事件的想法(即使返回某些结果)。

Any ideas on how can I handle the events on ViewSwiper when it's child returns false (even if some trues are returned).

PS:如果需要,我可以提供更多的信息,并接受不同的解决方案。

PS: I can give more info about this if needed, and accept different solutions also.

根据答案,我尝试了以下内容:

Based on answers I tried the following:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    onTouchEvent(ev);
    return intercept;
}

public boolean onTouchEvent(MotionEvent evt) {
    boolean x = super.onTouchEvent(evt);

    if (moveTracker.track(evt)) {
        intercept = moveTracker.getDirection() != Direction.VERTICAL;
        if (!intercept)
            getParent().requestDisallowInterceptTouchEvent(false);
    }

    return x;
}

仍然没有。

推荐答案

在滚动视图的 onTouchEvent()中尝试此功能

try this in onTouchEvent() of the scrollview

     //if (evt.getAction() == MotionEvent.ACTION_MOVE) {
    if (moveTracker.track(evt)){
       if (moveTracker.getDirection() == Direction.VERTICAL){
          //Or the direction you want the scrollview keep moving
          getParent().requestDisallowInterceptTouchEvent(true);

            }
        } 
 return true;

更新

请尝试以下操作自定义Scrollview

Please try the following to the custom Scrollview

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
    return false;
}

没有别的

这样我假设MotionEvent将在两个视图上执行。而且由于它们不冲突(一个是垂直的,另一个是水平的),这可以工作

This way i assume the MotionEvent will perform on both views. And since they don't conflict (One is vertical the other one is Horizontal) this could work

这篇关于如果孩子返回false,让父视图假定MotionEvents的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆