2013-03-11 94 views
3
public class GameActivity extends Activity { 
    private static final String TAG = "GameActivity"; 

    . . . 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     Log.d(TAG, "+ onTouchEvent(event:" + event + ")"); 
     Log.d(TAG, "- onTouchEvent()"); 
     return super.onTouchEvent(event); 
    } 

    . . . 
} 


public class GameView extends SurfaceView implements SurfaceHolder.Callback { 
    private static final String TAG = "GameView"; 

    . . . 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     Log.d(TAG, "+ onTouchEvent(event:" + event + ")"); 
     gestureDetector.onTouchEvent(event); 
     Log.d(TAG, "- onTouchEvent()"); 
     return super.onTouchEvent(event); 
    } 

    private SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() { 
     private static final String TAG = "GestureListener"; 

     @Override 
     public boolean onSingleTapConfirmed(MotionEvent event) { 
      Log.d(TAG, "+ onSingleTapConfirmed(event:" + event + ")"); 
      singleTapDetected = true; 
      Log.d(TAG, "- onSingleTapConfirmed()"); 
      return true; 
     } 

     @Override 
     public boolean onDoubleTap(MotionEvent event) { 
      Log.d(TAG, "+ onDoubleTap(event:" + event + ")"); 
      doubleTapDetected = true; 
      Log.d(TAG, "- onDoubleTap()"); 
      return true; 
     } 
    }; 

    private GestureDetector gestureDetector = new GestureDetector(getContext(), gestureListener); 

    . . . 
} 

我在AVD上運行它,在SurfaceView(GameView)上單擊一下。
據logcat的日誌:SurfaceView中帶有SimpleOnGestureListener的Android手勢檢測器

03-11 14:19:51.171: D/GameView(4839): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223172, downTime=27223172, deviceId=0, source=0x1002 }) 
03-11 14:19:51.171: D/GameView(4839): - onTouchEvent() 
03-11 14:19:51.171: D/GameActivity(4839): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223172, downTime=27223172, deviceId=0, source=0x1002 }) 
03-11 14:19:51.171: D/GameActivity(4839): - onTouchEvent() 
03-11 14:19:51.299: D/GameActivity(4839): + onTouchEvent(event:MotionEvent { action=ACTION_UP, id[0]=0, x[0]=1071.0, y[0]=437.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=27223303, downTime=27223172, deviceId=0, source=0x1002 }) 
03-11 14:19:51.299: D/GameActivity(4839): - onTouchEvent() 

有幾個問題:

  1. 爲什麼SimpleOnGestureListener不叫? (即使onTouchEvent()被稱爲和presummably行gestureDetector.onTouchEvent(event);被處決)

  2. 爲什麼GameActivity的onTouchEvent()得到ACTION_DOWNACTION_UP,但GameView的onTouchEvent()只得到ACTION_DOWN

有些事情我已經試過

  • 我在GameActivity類相同的代碼實現的GestureDetector如上圖所示,它的工作如預期,稱onSingleTapConfirmed()

  • 在GameView,而不是私人成員SimpleOnGestureListener,創建了一個私人class GestureListener extends SimpleOnGestureListener並用它來構建GestureDetector。我看到了與描述相同的行爲,沒有給監聽者打電話。

回答

7

我將代碼調試到Android源代碼GestureDetector類中。這解釋了爲什麼SimpleOnGestureListener不叫:

  • 的ACTION_DOWN被接收併產生內部TAP消息給GestureDetector消息處理程序。
  • 的處理程序將調用監聽onSingleTapConfirmed()只有當事件仍下降(!mStillDown
  • 事件仍然下跌,因爲從來沒有收到ACTION_UP事件。

所以你看,這兩個問題是相關的,當我發現爲什麼ACTION_UP沒有發出我將解決問題!

編輯

這樣就完成了答案,現在它正在工作。

  • 在GameView至super.onTouchEvent()調用返回false,因爲super類SurfaceView是查看,並返回false。這就是爲什麼ACTION_UP永遠不會被調用的原因
  • GameActivity中對super.onTouchEvent()的調用返回true,這就是在GameActivity上發出ACTION_UP的原因。

注:如果我設置GameView.setclickable(true)然後super.onTouchEvent()回報true這也是一個可接受的解決方案

現在我GameView代碼:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    Log.d(TAG, "+ onTouchEvent(event:" + event + ")"); 
    gestureDetector.onTouchEvent(event); 
    Log.d(TAG, "- onTouchEvent()"); 
    return true; 
} 

目前的logcat日誌:

03-11 16:32:06.629: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=977.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 }) 
03-11 16:32:06.629: D/GameView(5316): - onTouchEvent() 
03-11 16:32:06.641: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_MOVE, id[0]=0, x[0]=978.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 }) 
03-11 16:32:06.641: D/GameView(5316): - onTouchEvent() 
03-11 16:32:06.772: D/GameView(5316): + onTouchEvent(event:MotionEvent { action=ACTION_UP, id[0]=0, x[0]=978.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158772, downTime=35158623, deviceId=0, source=0x1002 }) 
03-11 16:32:06.772: D/GameView(5316): - onTouchEvent() 
03-11 16:32:06.931: D/GestureListener(5316): + onSingleTapConfirmed(event:MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=977.0, y[0]=414.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=35158623, downTime=35158623, deviceId=0, source=0x1002 }) 
03-11 16:32:06.931: D/GestureListener(5316): - onSingleTapConfirmed() 
+0

謝謝。我需要像你所建議的那樣做'surfaceView.setclickable(true)'。現在按我想要的方式工作! :) – Sufian 2014-09-04 09:29:53