3

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

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

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

但问题出在我在它上面添加的那个 PageView 上,如果 ImageViews 在它的 onTouchEvent 上返回 false,ViewSwiper 将处理这些事件并让另一个 PageView 进入屏幕,但是如果我在上面添加一个 ScrollView,所有事件将被 Scroll 消耗,ViewSwiper 将没有机会替换 PageView。

所以我发现返回 false onTouchEvent 的 ScrollView 父级可以假定它是事件,我编写了 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 会使任何进一步的事件被分派给父级,但是我需要这些事件来进行垂直滚动,所以我的想法是只有在用户移动水平时才返回 false,这就是我的代码的样子:

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 时处理事件的任何想法(即使返回了一些 true )。

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

依然没有。

4

2 回答 2

3

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 将在两个视图上执行。而且由于它们不冲突(一个是垂直的,另一个是水平的)这可以工作

于 2011-09-06T18:53:35.657 回答
1

根据weakwire的回答,我得出以下解决方案:

在 ViewSwiper 上

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

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

于 2011-09-08T15:02:10.913 回答