2011-09-06 48 views
3

我有一个需要事件处理的应用程序,这种应用程序需要一种不寻常的方式。如果子视图返回false,则让父视图假设MotionEvents

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

假设我有一个FrameLayout(我将从现在开始调用ViewSwiper)添加的所有视图都是MATCH_PARENT X MATCH_PARENT(我将调用PageView),它通过转换实际View来处理事件并将其替换基于移动的方向。 此组件我已经完成并正常工作(Using Animation to swipe views)。

但是问题出在我添加的PageView上,如果ImageViews在onTouchEvent上返回false,ViewSwiper将处理事件并让另一个PageView进入屏幕,但如果我添加了ScrollView那么所有的事件都将被Scroll使用,并且ViewSwiper将没有机会替换PageView。

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

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,这就是我的代码如下所示:

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将返回true在一些事件之后跟踪()并告诉用户正在移动的方向。

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

任何关于如何处理ViewSwiper上的事件的任何想法返回false(即使返回一些trues)。 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; 
} 

仍然一无所获。

回答

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; 

更新

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

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

,并没有别的

这样,我承担MotionEvent将在两个视图上执行。而且,由于他们不冲突(其中一个是垂直的,另一个是水平),这可能基于从weakwire答案工作

+0

这没有什么,一个问题,那么我应该实现onInterceptTouchEvent?如果是这样的话,我怎么知道孩子是否要求它拦截? –

+0

尝试返回总是true。这里的技术是,你需要默认所有的touchevent去到child.getParent()。requestDisallowInterceptTouchEvent(true)对一个子中断进行控制。如果所有事件(即使在滚动视图中)都由父视图控制,直到孩子拦截,而不是相反,这应该工作。 – weakwire

+0

那么,我将如何让父母处理所有事件并让孩子截取? –

1

,我来到了以下解决方案:

在ViewSwiper

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

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

+0

即使你自己基本解决了,也很乐意帮助你 – weakwire

+0

不,我只是需要一个小费,你的解决我的问题;) –

相关问题