Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> (轉)onTouchEvent方法的使用,ontouchevent方法

(轉)onTouchEvent方法的使用,ontouchevent方法

編輯:關於android開發

(轉)onTouchEvent方法的使用,ontouchevent方法


手機屏幕事件的處理方法onTouchEvent。該方法在View類中的定義,並且所有的View子類全部重寫了該方法,應用程序可以通過該方法處理手機屏幕的觸摸事件。該方法的簽名如下所示。

public boolean onTouchEvent(MotionEvent event)  

參數event:參數event為手機屏幕觸摸事件封裝類的對象,其中封裝了該事件的所有信息,例如觸摸的位置、觸摸的類型以及觸摸的時間等。該對象會在用戶觸摸手機屏幕時被創建。

返回值:該方法的返回值機理與鍵盤響應事件的相同,同樣是當已經完整地處理了該事件且不希望其他回調方法再次處理時返回true,否則返回false。

該方法並不像之前介紹過的方法只處理一種事件,一般情況下以下三種情況的事件全部由onTouchEvent方法處理,只是三種情況中的動作值不同。

屏幕被按下:當屏幕被按下時,會自動調用該方法來處理事件,此時MotionEvent.getAction()的值為MotionEvent.ACTION_DOWN,如果在應用程序中需要處理屏幕被按下的事件,只需重新該回調方法,然後在方法中進行動作的判斷即可。

屏幕被抬起:當觸控筆離開屏幕時觸發的事件,該事件同樣需要onTouchEvent方法來捕捉,然後在方法中進行動作判斷。當MotionEvent.getAction()的值為MotionEvent.ACTION_UP時,表示是屏幕被抬起的事件。

在屏幕中拖動:該方法還負責處理觸控筆在屏幕上滑動的事件,同樣是調用MotionEvent.getAction()方法來判斷動作值是否為MotionEvent.ACTION_MOVE再進行處理。

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舉例

 1 public class MyGesture extends Activity implements OnTouchListener {
 2     public void onCreate(Bundle savedInstanceState) {
 3         super.onCreate(savedInstanceState);
 4 
 5         setContentView(R.layout.main);
 6 
 7         TextView tv = (TextView) findViewById(R.id.tv);
 8 
 9         tv.setOnTouchListener(this);
10     }
11 
12     public boolean onTouch(View v, MotionEvent event)
13 
14     {
15         Toast.makeText(this, "Touch Touch", Toast.LENGTH_SHORT).show();
16 
17         return false;
18     }
19 
20 }

 

我們可以通過MotionEvent的getAction()方法來獲取Touch事件的類型,包括 ACTION_DOWN(按下觸摸屏), ACTION_MOVE(按下觸摸屏後移動受力點), ACTION_UP(松開觸摸屏)和ACTION_CANCEL(不會由用戶直接觸發)。借助對於用戶不同操作的判斷,結合getRawX()、 getRawY()、getX()和getY()等方法來獲取坐標後,我們可以實現諸如拖動某一個按鈕,拖動滾動條等功能。2. 當我們捕捉到Touch操作的時候,如何識別出用戶的Gesture?這裡我們需要GestureDetector.OnGestureListener接口的幫助,代碼如下:

 

  1 public class MyGesture extends Activity implements OnTouchListener, OnGestureListener
  2 
  3 {
  4 
  5     private GestureDetector mGestureDetector;
  6 
  7     public MyGesture()
  8 
  9     {
 10 
 11         mGestureDetector = new GestureDetector(this);
 12 
 13     }
 14 
 15     public void onCreate(Bundle savedInstanceState)
 16 
 17     {
 18 
 19         super.onCreate(savedInstanceState);
 20 
 21         setContentView(R.layout.main);
 22 
 23         TextView tv = (TextView) findViewById(R.id.tv);
 24 
 25         tv.setOnTouchListener(this);
 26 
 27         tv.setFocusable(true);
 28 
 29         tv.setClickable(true);
 30 
 31         tv.setLongClickable(true);
 32 
 33         mGestureDetector.setIsLongpressEnabled(true);
 34 
 35     }
 36 
 37     /*
 38      * *在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,
 39      * 將捕捉到的MotionEvent交給GestureDetector * 來分析是否有合適的callback函數來處理用戶的手勢
 40      */
 41 
 42     public boolean onTouch(View v, MotionEvent event)
 43 
 44     {
 45 
 46         return mGestureDetector.onTouchEvent(event);
 47 
 48     }
 49 
 50     // 用戶輕觸觸摸屏,由1個MotionEvent ACTION_DOWN觸發
 51 
 52     public boolean onDown(MotionEvent arg0)
 53 
 54     {
 55 
 56         Log.i("MyGesture", "onDown");
 57 
 58         Toast.makeText(this, "onDown", Toast.LENGTH_SHORT).show();
 59 
 60         return true;
 61 
 62     }
 63 
 64     /*
 65      * * 用戶輕觸觸摸屏,尚未松開或拖動,由一個1個MotionEvent ACTION_DOWN觸發 *
 66      * 注意和onDown()的區別,強調的是沒有松開或者拖動的狀態
 67      */
 68 
 69     public void onShowPress(MotionEvent e)
 70 
 71     {
 72 
 73         Log.i("MyGesture", "onShowPress");
 74 
 75         Toast.makeText(this, "onShowPress", Toast.LENGTH_SHORT).show();
 76 
 77     }
 78 
 79     // 用戶(輕觸觸摸屏後)松開,由一個1個MotionEvent ACTION_UP觸發
 80 
 81     public boolean onSingleTapUp(MotionEvent e)
 82 
 83     {
 84 
 85         Log.i("MyGesture", "onSingleTapUp");
 86 
 87         Toast.makeText(this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
 88 
 89         return true;
 90 
 91     }
 92 
 93     // 用戶按下觸摸屏、快速移動後松開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發
 94 
 95     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
 96 
 97     {
 98 
 99         Log.i("MyGesture", "onFling");
100 
101         Toast.makeText(this, "onFling", Toast.LENGTH_LONG).show();
102 
103         return true;
104 
105     }
106 
107     // 用戶按下觸摸屏,並拖動,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE觸發
108 
109     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
110 
111     {
112 
113         Log.i("MyGesture", "onScroll");
114 
115         Toast.makeText(this, "onScroll", Toast.LENGTH_LONG).show();
116 
117         return true;
118 
119     }
120 
121     // 用戶長按觸摸屏,由多個MotionEvent ACTION_DOWN觸發
122 
123     public void onLongPress(MotionEvent e)
124 
125     {
126 
127         Log.i("MyGesture", "onLongPress");
128 
129         Toast.makeText(this, "onLongPress", Toast.LENGTH_LONG).show();
130 
131     }
132 
133 }

 

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

 1 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
 2             float velocityY)
 3 
 4     {
 5 
 6         // 參數解釋:
 7 
 8         // e1:第1個ACTION_DOWN MotionEvent
 9 
10         // e2:最後一個ACTION_MOVE MotionEvent
11 
12         // velocityX:X軸上的移動速度,像素/秒
13 
14         // velocityY:Y軸上的移動速度,像素/秒
15 
16         // 觸發條件 :
17 
18         // X軸的坐標位移大於FLING_MIN_DISTANCE,且移動速度大於FLING_MIN_VELOCITY個像素/秒
19 
20         final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
21 
22         if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
23                 && Math.abs(velocityX) > FLING_MIN_VELOCITY)
24 
25         {
26 
27             // Fling left
28 
29             Log.i("MyGesture", "Fling left");
30 
31             Toast.makeText(this, "Fling Left", Toast.LENGTH_SHORT).show();
32 
33         }
34 
35         else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
36                 && Math.abs(velocityX) > FLING_MIN_VELOCITY)
37 
38         {
39 
40             // Fling right
41 
42             Log.i("MyGesture", "Fling right");
43 
44             Toast.makeText(this, "Fling Right", Toast.LENGTH_SHORT).show();
45 
46         }
47 
48         return false;
49 
50     }

 

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

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved