从其他视图拖动时检测视图上的触摸事件

如果用户触摸视图A并在视图B上拖动到底部,如何检测触摸事件。我想在视图B中检测触摸事件。

我在视图B中添加了触摸侦听器,但如果用户最初触摸A并拖过B,则不会接收事件。

在此处输入图像描述

您可以使用下面的代码来实现您的请求:

测试视图边界的方法 (用于代码beloow)

Rect outRect = new Rect(); int[] location = new int[2]; private boolean isViewInBounds(View view, int x, int y){ view.getDrawingRect(outRect); view.getLocationOnScreen(location); outRect.offset(location[0], location[1]); return outRect.contains(x, y); } 

使用两个TextView测试

  final TextView viewA = (TextView) findViewById(R.id.textView); final TextView viewB = (TextView) findViewById(R.id.textView2); 

设置视图A.

OnClickListener ,需要空OnClickListener才能使OnTouchListener保持活动状态

  viewA.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) {} }); viewA.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int x = (int)event.getRawX(); int y = (int)event.getRawY(); if(event.getAction() == MotionEvent.ACTION_UP){ if(isViewInBounds(viewB, x, y)) viewB.dispatchTouchEvent(event); else if(isViewInBounds(viewA, x, y)){ Log.d(TAG, "onTouch ViewA"); //Here goes code to execute on onTouch ViewA } } // Further touch is not handled return false; } }); 

设置视图B.

仅当您还要按viewB并拖动到viewA时,才需要这样做

  viewB.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) {} }); viewB.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int x = (int)event.getRawX(); int y = (int)event.getRawY(); if(event.getAction() == MotionEvent.ACTION_UP){ if(isViewInBounds(viewA, x, y)) viewA.dispatchTouchEvent(event); else if(isViewInBounds(viewB, x, y)){ Log.d(TAG, "onTouch ViewB"); //Here goes code to execute on onTouch ViewB } } // Further touch is not handled return false; } }); 

问候。

我确定您需要在ViewGroup中覆盖包含视图A和​​B的ViewGroup.dispatchTouchEvent(MotionEvent ev)方法。原始实现在容器接收MotionEvent.getAction() == MotionEvent.ACTION_DOWN然后调度时定义目标视图所有以下触摸事件到目标视图,直到接收到MotionEvent.getAction() == MotionEvent.ACTION_UPMotionEvent.ACTION_CANCEL

在您的情况下,目标视图是A或者包含器本身(容器上的onInterceptTouchEvent(MotionEvent ev)方法实现)。 因此,您应该覆盖此类行为,并将触摸事件不仅发送到目标视图,还发送到触摸区域下的所有视图(例如,查看B)。

如果您有兴趣,可以共享代码示例,我会尽力帮助您。

如果从视图A的onTouchEvent返回true,则不传播该事件。 在这种特殊情况下,当A低于B时,从onTouch视图A返回false。

如果你可以发布一些代码也会有所帮助。

View A中 ,覆盖onTouchEvent ,如下所示:

 @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getRawX(); float y = event.getRawY(); if ( (B.getLeft() < = x <= B.getRight()) && (B.getTop() <= y <= B.getBottom()) ) { Log.i("A", "Motion Event is currently above B"); B.dispatchTouchEvent(event); } return true; } 

View B中 ,重写相同的方法,确保返回false

 @Override public boolean onTouchEvent(MotionEvent event) { //TODO handle touch event return false;//this will allow A to continue using the event } 

尝试使用拖放框架。

当您在View B上时,请手动将其onTouch

 if (viewBRect.contains(x, y)) { viewBsonTouch(view, motionEvent); }