如果child返回false,则让父View假定MotionEvents

时间:2011-09-06 18:33:36

标签: android event-handling android-scrollview android-event

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

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

假设我有一个FrameLayout(我现在称之为ViewSwiper),其上添加的所有Views都是MATCH_PARENT X MATCH_PARENT(我称之为PageView),它通过翻译实际的View来处理事件并替换它在移动的方向。 我已经完成并正常工作的这个组件(Using Animation to swipe views)。

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

所以我想通过返回ScrollView的假onTouchEvent,父可以假设它的事件,我编写了ScrollView的这个子类来测试它:

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时返回falses,这就是我的代码: / p>

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,并告诉用户移动的方向。

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

有关如何处理ViewSwiper上的事件的任何想法,当它的子节点返回false时(即使返回了一些真值)。

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

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

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

仍然没有。

2 个答案:

答案 0 :(得分:3)

在scrollview的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;

更新

请尝试以下自定义Scrollview

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

没有别的

这种方式我假设MotionEvent将在两个视图上执行。而且由于它们没有冲突(一个是垂直的,另一个是水平的)这可以起作用

答案 1 :(得分:1)

根据weakwire的回答,我找到了以下解决方案:

在ViewSwiper上

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(!super.dispatchTouchEvent(ev))
            onTouchEvent(ev);
        return true;
    }

在ScrollHorizo​​ntal上,当我不再需要时,我会在dispatchTouchEvent上返回false。