2011-09-30 109 views
12

我有onLongPress並根據此代碼放在按鈕onDoubleTap操作:爲什麼android onLongPress總是在onDoubleTap之後被觸發?

... 
GestureDetector detector = new GestureDetector(this, new TapDetector()); 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector()); 
    ... 
} 

private class TapDetector extends GestureDetector.SimpleOnGestureListener { 

    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     // Do something 
     return true; 
    } 

    @Override 
    public void onLongPress(MotionEvent e) {   
     // Do something   
    } 
} 

Button incomeButton = (Button) findViewById(R.id.income); 
button.setOnTouchListener(new OnTouchListener(){ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     detector.onTouchEvent(event); 
     return true; 
    } 
}); 

我總是看到onLongPress解僱onDoubleClick發射和執行之後。這種違反直覺行爲的原因是什麼?如何避免這種行爲?

修訂 我已經改變了我的源代碼,以更具體

public class MainActivity extends Activity { 
private GestureDetector detector; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector());  

    Button button = (Button) findViewById(R.id.button);     
    button.setOnTouchListener(new OnTouchListener(){ 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      System.out.println("************* onTouch *************"); 
      detector.onTouchEvent(event); 
      return true; 
     } 
    });       
}  

class TapDetector extends GestureDetector.SimpleOnGestureListener { 

    @Override 
    public void onLongPress(MotionEvent e) { 
     System.out.println("************* onLongPress *************");      
    }   

    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     System.out.println("************* onDoubleTap *************"); 
     Intent intent = new Intent();   
     intent.setClass(getApplicationContext(), NewActivity.class); 
     intent.putExtra("parameterName", "parameter"); 
     startActivity(intent);    
     return true; 
    }    
}   
} 

這是一個日誌onDoubleTap後,我點擊。你可以在最後看到onLongPress - 我從不點擊它。

I/System.out(1106): ************* onTouch ************* 
I/System.out(1106): ************* onTouch ************* 
I/System.out(1106): ************* onTouch ************* 
I/System.out(1106): ************* onDoubleTap ************* 
I/ActivityManager( 59): Starting activity: Intent { cmp=my.tapdetector/.NewActivity (has extras) } 
I/ActivityManager( 59): Displayed activity my.tapdetector/.NewActivity: 324 ms (total 324 ms) 
I/System.out(1106): ************* onLongPress ************* 

UPDATE我已經找到了解決辦法。爲了避免onLongPress發射變化需要做的事情:

第一:detector.setIsLongpressEnabled();在onTouch(視圖V,MotionEvent事件)

button.setOnTouchListener(new OnTouchListener(){ 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      System.out.println("************* onTouch *************"); 
      detector.onTouchEvent(event); 
      detector.setIsLongpressEnabled(true); 
      return true; 
     } 
    }); 

二:添加detector.setIsLongpressEnabled();在onDoubleTap(MotionEvent五)

 public boolean onDoubleTap(MotionEvent e) { 
     detector.setIsLongpressEnabled(false); 
     System.out.println("************* onDoubleTap *************"); 
     Intent intent = new Intent();   
     intent.setClass(getApplicationContext(), NewActivity.class); 
     intent.putExtra("parameterName", "parameter"); 
     startActivity(intent);    
     return true; 
    } 
+0

不能重複這個,對不起。在這兩個事件上使用Log.i()時,它們會被正確調用。 –

+0

體面的工作,看起來像一個內置的競爭條件,如接受答案的評論中所述。謝謝。 –

回答

3

從技術上講這不應該發生

case MotionEvent.ACTION_DOWN: 
     mLastMotionX = x; 
     mLastMotionY = y; 
     mCurrentDownEvent = MotionEvent.obtain(ev); 
     mAlwaysInTapRegion = true; 
     mInLongPress = false; 

     if (mIsLongpressEnabled) { 
      mHandler.removeMessages(LONG_PRESS); 
      mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() 
        + tapTime + longpressTime); 
     } 
     mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + tapTime); 

因爲在ACTION_DOWN或ACTION_UP事件,所有事件都是從隊列中刪除的LONG_PRESS消息。因此,第二次點擊下面的代碼將刪除長按事件。

mHandler.removeMessages(LONG_PRESS); 

忍者編輯:哈克解決方法您的問題

 @Override 
    public void onLongPress(MotionEvent e) { 
     if(MainActivity.this.hasWindowFocus()) 
     { 
      Log.d("Touchy", "Long tap");  
     } 
    } 
+1

剛纔我發現,如果在onDoubleClick方法上設置了breake點,我總是會在onDoubleTap **後面的onDoubleTap **下調用**。如果我刪除了breake點 - 一切都OK ...... – isabsent

+1

它是有道理的,然後,'mCurrentDownEvent.getDownTime()+ tapTime + longpressTime'已過期 – Reno

+0

看來,如果我有onDoubleTap方法長時間處理身體,我總是會不會打開LongPress? – isabsent

0

你看總是onLongPress在你的代碼,因爲解僱你消耗onDoubleTap事件之前所推出的意圖。
您可以通過
public void setIsLongpressEnabled (boolean isLongpressEnabled)
禁用onLongPress並使用onDown方法執行您的操作。

相關問題