android:onTouch()和onTouchEvent()的區別?看完這篇文章就知道了

來源:互聯網
上載者:User

 Android Touch Screen 與傳統Click Touch Screen不同,會有一些手勢(Gesture),例如Fling,Scroll等等。這些Gesture會使使用者體驗大大提升。

Android中的Gesture識別(detector)是通過GestureDetector.OnGestureListener介面實現的。

首先,Android事件處理機制是基於Listener實現的,比如觸控螢幕相關的事件,就是通過onTouchListener實現;

其次,所有View的子類都可以通過setOnTouchListener()、setOnKeyListener()等方法來添加對某一類事件的Listener;

第三,Listener一般會以Interface的方式來提供,其中包含一個或多個abstract方法,我們需要實現這些方法來完成 onTouch()、onKey()等操作。這樣,程式便可以在特定的事件被dispatch到該view的時候,通過callback函數給予適當的響 應。

 

1. Touch Screen Click舉例

public   class  MyGesture  extends  Activity  implements  OnTouchListener

{       

public   void  onCreate(Bundle savedInstanceState)

 {           

super .onCreate(savedInstanceState);           

setContentView(R.layout.main);           

TextView tv = (TextView) findViewById(R.id.tv);          

 tv.setOnTouchListener( this );      

 }       

public   boolean  onTouch(View v, MotionEvent event)

 {           

Toast.makeText( this ,  "Touch Touch" , Toast.LENGTH_SHORT).show();           

return   false ;      

 } 

  } 

我們可以通過MotionEvent的getAction()方法來擷取Touch事件的類型,包括 ACTION_DOWN(按下觸控螢幕), ACTION_MOVE(按下觸控螢幕後移動受力點), ACTION_UP(鬆開觸控螢幕)和ACTION_CANCEL(不會由使用者直接觸發)。藉助對於使用者不同操作的判斷,結合getRawX()、 getRawY()、getX()和getY()等方法來擷取座標後,我們可以實現諸如拖動某一個按鈕,拖動捲軸等功能。

 

2. 當我們捕捉到Touch操作的時候,如何識別出使用者的Gesture?這裡我們需要GestureDetector.OnGestureListener介面的協助,代碼如下:

public   class  MyGesture  extends  Activity  implements  OnTouchListener, OnGestureListener

{       

private  GestureDetector mGestureDetector;       

public  MyGesture()

 {           

mGestureDetector =  new  GestureDetector( this );      

 }       

public   void  onCreate(Bundle savedInstanceState)

{           

super .onCreate(savedInstanceState);           

setContentView(R.layout.main);          

 TextView tv = (TextView) findViewById(R.id.tv);          

 tv.setOnTouchListener( this );          

 tv.setFocusable( true );           

tv.setClickable( true );           

tv.setLongClickable( true );           

mGestureDetector.setIsLongpressEnabled( true );       

}              

  /*       * 在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector        * 來分析是否有合適的callback函數來處理使用者的手勢        */         

public   boolean  onTouch(View v, MotionEvent event)

{          

  return  mGestureDetector.onTouchEvent(event);      

 }          

// 使用者輕觸觸控螢幕,由1個MotionEvent ACTION_DOWN觸發       

public   boolean  onDown(MotionEvent arg0)

{           

Log.i( "MyGesture" ,  "onDown" );           

Toast.makeText( this ,  "onDown" , Toast.LENGTH_SHORT).show();           

return   true ;       

}               

/*       * 使用者輕觸觸控螢幕,尚未鬆開或拖動,由一個1個MotionEvent ACTION_DOWN觸發        * 注意和onDown()的區別,強調的是沒有鬆開或者拖動的狀態        */       

public   void  onShowPress(MotionEvent e)

 {           

Log.i( "MyGesture" ,  "onShowPress" );           

Toast.makeText( this ,  "onShowPress" , Toast.LENGTH_SHORT).show();       

}               

// 使用者(輕觸觸控螢幕後)鬆開,由一個1個MotionEvent ACTION_UP觸發       

public   boolean  onSingleTapUp(MotionEvent e)

{          

 Log.i( "MyGesture" ,  "onSingleTapUp" );           

Toast.makeText( this ,  "onSingleTapUp" , Toast.LENGTH_SHORT).show();           

return   true ;      

 }              

  // 使用者按下觸控螢幕、快速移動後鬆開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發       

public   boolean  onFling(MotionEvent e1, MotionEvent e2,  float  velocityX,  float  velocityY)

{           

Log.i( "MyGesture" ,  "onFling" );           

Toast.makeText( this ,  "onFling" , Toast.LENGTH_LONG).show();           

return   true ;       

}              

  // 使用者按下觸控螢幕,並拖動,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE觸發       

public   boolean  onScroll(MotionEvent e1, MotionEvent e2,  float  distanceX,  float  distanceY)

{           

Log.i( "MyGesture" ,  "onScroll" );          

 Toast.makeText( this ,  "onScroll" , Toast.LENGTH_LONG).show();           

return   true ;      

 }              

  // 使用者長按觸控螢幕,由多個MotionEvent ACTION_DOWN觸發       

public   void  onLongPress(MotionEvent e)

 {           

Log.i( "MyGesture" ,  "onLongPress" );           

Toast.makeText( this ,  "onLongPress" , Toast.LENGTH_LONG).show();      

 } 

  }

3. Fling事件的處理代碼:除了第一個觸發Fling的ACTION_DOWN和最後一個ACTION_MOVE中包含的座標等資訊外,我們還可以根據用 戶在X軸或者Y軸上的移動速度作為條件。比如下面的代碼中我們就在使用者移動超過100個像素,且X軸上每秒的移動速度大於200像素時才進行處理。

public   boolean  onFling(MotionEvent e1, MotionEvent e2,  float  velocityX,  float  velocityY)

 {      

// 參數解釋:       

// e1:第1個ACTION_DOWN MotionEvent      

// e2:最後一個ACTION_MOVE MotionEvent       

// velocityX:X軸上的移動速度,像素/秒      

// velocityY:Y軸上的移動速度,像素/秒          

// 觸發條件 :       

// X軸的座標位移大於FLING_MIN_DISTANCE,且移動速度大於FLING_MIN_VELOCITY個像素/秒               

final   int  FLING_MIN_DISTANCE =  100 , FLING_MIN_VELOCITY =  200 ;       

if  (e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY)

{           

// Fling left           

Log.i( "MyGesture" ,  "Fling left" );           

Toast.makeText( this ,  "Fling Left" , Toast.LENGTH_SHORT).show();       

}

else   if  (e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY)

{           

// Fling right           

Log.i( "MyGesture" ,  "Fling right" );           

Toast.makeText( this ,  "Fling Right" , Toast.LENGTH_SHORT).show();       

}       

return   false ;  

這個例子中,tv.setLongClickable(true)是必須的,因為 只有這樣,view才能夠處理不同於Tap(輕觸)的hold(即ACTION_MOVE,或者多個ACTION_DOWN),我們同樣可以通過layout定義中的android:longClickable來做到這一點。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.