我正在使用 SurfaceView
将触摸绘制为覆盖在我的应用程序上。我希望我的其他 View
能够与 SurfaceView
同时响应触摸事件,因此在包含的 ViewGroup
中他们都是我添加的
我的 View 组:
@Override
public boolean onInterceptTouchEvent(MotionEvent motionEvent){
mSurfaceView.onTouchEvent(motionEvent);
return false;
}
由于 SurfaceView
位于其他 View 的后面,因此效果很好。 SurfaceView
和它上面的 View
都会收到 MotionEvent
。
然后 SurfaceView
进一步将事件转发给渲染到其中的线程。
我的表面 View :
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
if (mThreadHandler != null){
mThreadHandler.sendMotionEvent(motionEvent);
}
return true;
}
然后当我的渲染线程收到它运行的消息时:
我的渲染线程:
private void handleMotionEvent(MotionEvent motionEvent){
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
float x = motionEvent.getX(); // Breakpoint 1
float x2 = motionEvent.getX(); // Breakpoint 2
float x3 = motionEvent.getX(); // Breakpoint 3
path.moveTo(motionEvent.getX(), motionEvent.getY());
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(motionEvent.getX(),motionEvent.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// do nothing
break;
default:
break;
}
}
当我在 Debug模式下运行此代码并在 ViewGroup
上滑动手指时,x
、x2
和 的值x3
都不同。我怀疑这是因为 UI 线程在被 MyRenderThread
使用之前重新使用了 MotionEvent。我该如何解决这个问题?
糟糕的解决方案是将每个 MotionEvent
复制为一个新对象并将其传递给 MyRenderThread
,但这需要很多对象创建/销毁。
最佳答案
MotionEvent.obtain(MotionEvent ev)
将从作为输入事件副本的池中返回一个 MotionEvent
。
我的 View 组:
@Override
public boolean onInterceptTouchEvent(MotionEvent motionEvent){
mSurfaceView.fowardTouchEvent(MotionEvent.obtain(motionEvent);
return false;
}
我的表面 View :
public void forwardTouchEvent(MotionEvent motionEvent){
if (scratchpadThreadHandler != null){
scratchpadThreadHandler.sendMotionEvent(motionEvent);
}
}
我的渲染线程:
private void handleMotionEvent(MotionEvent motionEvent){
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
float x = motionEvent.getX(); // Breakpoint 1
float x2 = motionEvent.getX(); // Breakpoint 2
float x3 = motionEvent.getX(); // Breakpoint 3
path.moveTo(motionEvent.getX(), motionEvent.getY());
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(motionEvent.getX(),motionEvent.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// do nothing
break;
default:
break;
}
motionEvent.recycle(); // Mark this MotionEvent as available for recycling.
}
这样每个事件仍然被复制(不知道该怎么做)但至少对象被重用。
关于android - MotionEvent 在仍在使用时被回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25942640/