在我的Android应用中,我有一个接收触摸事件的自定义View
。但是,每次触摸它时它都没有反应 - 只是有时候。据我所知,如果我触摸屏幕,移动我的手指,然后松开 - 即使我只移动一点 - 事件被拾取,但如果我太快地点击屏幕让我的手指滑过它, 什么都没发生。我该如何解决这个问题?
以下是View的代码:
public class SpeedShooterGameView extends GameActivity.GameView {
public SpeedShooterGameView(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
@Override
protected GameThread getNewThread(SurfaceHolder holder, Context context) {
return new SpeedShooterGameThread(holder, context);
}
// Program is driven by screen touches
public boolean onTouchEvent(MotionEvent event) {
SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread();
if (thread.isRunning()) {
return thread.recieveTouch(event);
} else {
return false;
}
}
}
我非常确信行SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread();
中返回的对象正如我所期望的那样工作,但如果上面的代码看起来很好,我也会发布该类的相关代码。调用thread.recieveTouch(event);
时,MotionEvent
将被发送到另一个线程。
编辑:我会继续发布SpeedShooterGameThread
的代码:
public class SpeedShooterGameThread extends GameActivity.GameView.GameThread {
//... snip ...
private Queue<MotionEvent> touchEventQueue;
//... snip ...
public synchronized final void newGame() { //called from the constructor, used to go to a known stable state
//... snip ...
touchEventQueue = new LinkedList<MotionEvent>();
//... snip ...
}
//...snip...
public synchronized boolean recieveTouch(MotionEvent event) {
return touchEventQueue.offer(event);
}
private synchronized void processTouchEvents() {
synchronized (touchEventQueue) {
while (!touchEventQueue.isEmpty()) {
MotionEvent event = touchEventQueue.poll();
if (event == null) {
continue;
}
//... snip ....
}
}
}
//... snip ...
}
答案 0 :(得分:0)
我通过完全取消Queue<MotionEvent>
来修复错误。我的代码现在看起来像这样:
线程不再使用Queue
,并且在调用MotionEvents
时会立即处理recieveTouch()
:
public class SpeedShooterGameThread extends GameActivity.GameView.GameThread {
//The touchEvent member has been removed.
//... snip ...
public synchronized final void newGame() { //called from the constructor, used to go to a known stable state
// touchEvents is no longer initialized.
//...snip...
}
//...snip...
public synchronized boolean recieveTouch(MotionEvent event) {
//Immediately handle the MotionEvent here,
//or return false if the event isn't processed
}
// The processTouchEvents() method is removed.
//... snip ...
}
视图未更改:
public class SpeedShooterGameView extends GameActivity.GameView {
public SpeedShooterGameView(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
@Override
protected GameThread getNewThread(SurfaceHolder holder, Context context) {
return new SpeedShooterGameThread(holder, context);
}
// Program is driven by screen touches
public boolean onTouchEvent(MotionEvent event) {
SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread();
if (thread.isRunning()) {
return thread.recieveTouch(event);
} else {
return false;
}
}
}