让家长查看假设MotionEvents如果孩子返回false家长、孩子、MotionEvents、false

2023-09-06 17:19:23 作者:女汉子也有春天

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

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(我会打电话浏览量),它是通过把实际查看,取而代之的是基于处理事件在移动的方向。 这部分我已经完成,并正常工作(使用动画刷卡意见)。

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 ).

但问题是,在该浏览量我加在它上面,以免返回false它的的onTouchEvent ImageViews时,ViewSwiper会处理事件,并让另一浏览量进入屏幕,但如果我增加一个滚动型上中,所有的事件将通过滚动和ViewSwiper被消耗不会有机会来替换浏览量

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.

所以我想通了,回到了滚动型假的onTouchEvent家长可以假设它是事件,我写了这个子类滚动型进行测试:

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进行任何进一步的活动,以获得分派到父,但我需要这些事件对于垂直滚动,所以我有这个想法返回falses仅当用户正在水平,这就是我的code相这样的:

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会返回一些事件之后真正步入正轨(),告诉哪个方向用户移动

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

但是,在这种情况下,滚动型保持接收事件,因为它的收益上的第一事件真

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

我如何可以处理ViewSwiper的事件时,它的孩子返回false(即使某些trues返回)。

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.

我试过如下:

@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;
}

仍然一无所获。

Still nothing.

推荐答案

尝试在的onTouchEvent()滚动视图的

     //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;

更新

请尝试以下的自定义滚动型

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