1. 程式人生 > >用戶手勢檢測-GestureDetector使用詳解

用戶手勢檢測-GestureDetector使用詳解

而且 使用詳解 lib term show bundle mas 多次 cli

一、概述

當用戶觸摸屏幕的時候,會產生許多手勢,例如down,up,scroll,filing等等。
一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,但是這個方法太過簡單,如果需要處理一些復雜的手勢,用這個接口就會很麻煩(因為我們要自己根據用戶觸摸的軌跡去判斷是什麽手勢)。
Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢,主要是通過他的onTouchEvent(event)方法完成了不同手勢的識別。雖然他能識別手勢,但是不同的手勢要怎麽處理,應該是提供給程序員實現的。

GestureDetector這個類對外提供了兩個接口和一個外部類
接口:OnGestureListener,OnDoubleTapListener
內部類:SimpleOnGestureListener

這個外部類,其實是兩個接口中所有函數的集成,它包含了這兩個接口裏所有必須要實現的函數而且都已經重寫,但所有方法體都是空的;不同點在於:該類是static class,程序員可以在外部繼承這個類,重寫裏面的手勢處理方法。

下面我們先看OnGestureListener接口;

二、GestureDetector.OnGestureListener---接口

1、基本講解

如果我們寫一個類並implements OnGestureListener,會提示有幾個必須重寫的函數,加上之後是這個樣子的:

[java] view plain copy
  1. private class gesturelistener implements GestureDetector.OnGestureListener{
  2. public boolean onDown(MotionEvent e) {
  3. // TODO Auto-generated method stub
  4. return false;
  5. }
  6. public void onShowPress(MotionEvent e) {
  7. // TODO Auto-generated method stub
  8. }
  9. public boolean onSingleTapUp(MotionEvent e) {
  10. // TODO Auto-generated method stub
  11. return false;
  12. }
  13. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  14. float distanceX, float distanceY) {
  15. // TODO Auto-generated method stub
  16. return false;
  17. }
  18. public void onLongPress(MotionEvent e) {
  19. // TODO Auto-generated method stub
  20. }
  21. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  22. float velocityY) {
  23. // TODO Auto-generated method stub
  24. return false;
  25. }
  26. }

可見,這裏總共重寫了六個函數,這些函數都在什麽情況下才會觸發呢,下面講一下:

OnDown(MotionEvent e):用戶按下屏幕就會觸發;
onShowPress(MotionEvent e):如果是按下的時間超過瞬間,而且在按下的時候沒有松開或者是拖動的,那麽onShowPress就會執行,具體這個瞬間是多久,我也不清楚呃……
onLongPress(MotionEvent e):長按觸摸屏,超過一定時長,就會觸發這個事件
觸發順序:
onDown->onShowPress->onLongPress
onSingleTapUp(MotionEvent e):從名子也可以看出,一次單獨的輕擊擡起操作,也就是輕擊一下屏幕,立刻擡起來,才會有這個觸發,當然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會觸發這個事件
觸發順序:
點擊一下非常快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點擊一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用戶按下觸摸屏、快速移動後松開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發
參數解釋:
e1:第1個ACTION_DOWN MotionEvent
e2:最後一個ACTION_MOVE MotionEvent
velocityX:X軸上的移動速度,像素/秒
velocityY:Y軸上的移動速度,像素/秒
onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖動事件。無論是用手拖動view,或者是以拋的動作滾動,都會多次觸發,這個方法 在ACTION_MOVE動作發生時就會觸發
滑屏:手指觸動屏幕後,稍微滑動後立即松開
onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
拖動
onDown------》onScroll----》onScroll------》onFiling

可見,無論是滑屏,還是拖動,影響的只是中間OnScroll觸發的數量多少而已,最終都會觸發onFling事件!

2、實例

要使用GestureDetector,有三步要走:

1、創建OnGestureListener監聽函數:
可以使用構造實例:

[java] view plain copy
  1. GestureDetector.OnGestureListener listener = new GestureDetector.OnGestureListener(){
  2. };

也可以構造類:

[java] view plain copy
  1. private class gestureListener implements GestureDetector.OnGestureListener{
  2. }

2、創建GestureDetector實例mGestureDetector:

構造函數有下面三個,根據需要選擇:

[java] view plain copy
  1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
  2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
  3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);

3、onTouch(View v, MotionEvent event)中攔截:

[java] view plain copy
  1. public boolean onTouch(View v, MotionEvent event) {
  2. return mGestureDetector.onTouchEvent(event);
  3. }

4、控件綁定

[java] view plain copy
  1. TextView tv = (TextView)findViewById(R.id.tv);
  2. tv.setOnTouchListener(this);

現在進入實例階段:

首先,在主布局頁面添加一個textView,並將其放大到整屏,方便在其上的手勢識別,代碼為:

[java] view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context="com.example.gesturedetectorinterface.MainActivity" >
  6. <TextView
  7. android:id="@+id/tv"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:layout_margin="50dip"
  11. android:background="#ff00ff"
  12. android:text="@string/hello_world" />
  13. </RelativeLayout>

然後在JAVA代碼中,依據上面的三步走原則,寫出代碼,並在所有的手勢下添加上Toast提示並寫上Log

[java] view plain copy
  1. public class MainActivity extends Activity implements OnTouchListener{
  2. private GestureDetector mGestureDetector;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. mGestureDetector = new GestureDetector(new gestureListener()); //使用派生自OnGestureListener
  8. TextView tv = (TextView)findViewById(R.id.tv);
  9. tv.setOnTouchListener(this);
  10. tv.setFocusable(true);
  11. tv.setClickable(true);
  12. tv.setLongClickable(true);
  13. }
  14. /*
  15. * 在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector
  16. * 來分析是否有合適的callback函數來處理用戶的手勢
  17. */
  18. public boolean onTouch(View v, MotionEvent event) {
  19. return mGestureDetector.onTouchEvent(event);
  20. }
  21. private class gestureListener implements GestureDetector.OnGestureListener{
  22. // 用戶輕觸觸摸屏,由1個MotionEvent ACTION_DOWN觸發
  23. public boolean onDown(MotionEvent e) {
  24. Log.i("MyGesture", "onDown");
  25. Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();
  26. return false;
  27. }
  28. /*
  29. * 用戶輕觸觸摸屏,尚未松開或拖動,由一個1個MotionEvent ACTION_DOWN觸發
  30. * 註意和onDown()的區別,強調的是沒有松開或者拖動的狀態
  31. *
  32. * 而onDown也是由一個MotionEventACTION_DOWN觸發的,但是他沒有任何限制,
  33. * 也就是說當用戶點擊的時候,首先MotionEventACTION_DOWN,onDown就會執行,
  34. * 如果在按下的瞬間沒有松開或者是拖動的時候onShowPress就會執行,如果是按下的時間超過瞬間
  35. * (這塊我也不太清楚瞬間的時間差是多少,一般情況下都會執行onShowPress),拖動了,就不執行onShowPress。
  36. */
  37. public void onShowPress(MotionEvent e) {
  38. Log.i("MyGesture", "onShowPress");
  39. Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();
  40. }
  41. // 用戶(輕觸觸摸屏後)松開,由一個1個MotionEvent ACTION_UP觸發
  42. ///輕擊一下屏幕,立刻擡起來,才會有這個觸發
  43. //從名子也可以看出,一次單獨的輕擊擡起操作,當然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以這個事件 就不再響應
  44. public boolean onSingleTapUp(MotionEvent e) {
  45. Log.i("MyGesture", "onSingleTapUp");
  46. Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
  47. return true;
  48. }
  49. // 用戶按下觸摸屏,並拖動,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE觸發
  50. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  51. float distanceX, float distanceY) {
  52. Log.i("MyGesture22", "onScroll:"+(e2.getX()-e1.getX()) +" "+distanceX);
  53. Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();
  54. return true;
  55. }
  56. // 用戶長按觸摸屏,由多個MotionEvent ACTION_DOWN觸發
  57. public void onLongPress(MotionEvent e) {
  58. Log.i("MyGesture", "onLongPress");
  59. Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();
  60. }
  61. // 用戶按下觸摸屏、快速移動後松開,由1個MotionEvent ACTION_DOWN, 多個ACTION_MOVE, 1個ACTION_UP觸發
  62. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  63. float velocityY) {
  64. Log.i("MyGesture", "onFling");
  65. Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();
  66. return true;
  67. }
  68. };
  69. }

源碼在博客底部給出。

三、GestureDetector.OnDoubleTapListener---接口

1、構建

有兩種方式設置雙擊監聽:

方法一:新建一個類同時派生自OnGestureListener和OnDoubleTapListener:

[java] view plain copy
  1. private class gestureListener implements GestureDetector.OnGestureListener,GestureDetector.OnDoubleTapListener{
  2. }

方法二:使用GestureDetector::setOnDoubleTapListener();函數設置監聽:

[java] view plain copy
  1. //構建GestureDetector實例
  2. mGestureDetector = new GestureDetector(new gestureListener()); //使用派生自OnGestureListener
  3. private class gestureListener implements GestureDetector.OnGestureListener{
  4. }
  5. //設置雙擊監聽器
  6. mGestureDetector.setOnDoubleTapListener(new doubleTapListener());
  7. private class doubleTapListener implements GestureDetector.OnDoubleTapListener{
  8. }

註意:大家可以看到無論在方法一還是在方法二中,都需要派生自GestureDetector.OnGestureListener,前面我們說過GestureDetector 的構造函數,如下:

[java] view plain copy
  1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
  2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
  3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);

可以看到,在構造函數中,除了後面要講的SimpleOnGestureListener 以外的其它兩個構造函數都必須是OnGestureListener的實例。所以要想使用OnDoubleTapListener的幾個函數,就必須先實現OnGestureListener。

2、函數講解:

首先看一下OnDoubleTapListener接口必須重寫的三個函數:

[java] view plain copy
  1. private class doubleTapListener implements GestureDetector.OnDoubleTapListener{
  2. public boolean onSingleTapConfirmed(MotionEvent e) {
  3. // TODO Auto-generated method stub
  4. return false;
  5. }
  6. public boolean onDoubleTap(MotionEvent e) {
  7. // TODO Auto-generated method stub
  8. return false;
  9. }
  10. public boolean onDoubleTapEvent(MotionEvent e) {
  11. // TODO Auto-generated method stub
  12. return false;
  13. }
  14. }

onSingleTapConfirmed(MotionEvent e):單擊事件。用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢,如果只點擊一次,系統等待一段時間後沒有收到第二次點擊則判定該次點擊為SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。觸發順序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed
關於onSingleTapConfirmed和onSingleTapUp的一點區別: OnGestureListener有這樣的一個方法onSingleTapUp,和onSingleTapConfirmed容易混淆。二者的區別是:onSingleTapUp,只要手擡起就會執行,而對於onSingleTapConfirmed來說,如果雙擊的話,則onSingleTapConfirmed不會執行。

onDoubleTap(MotionEvent e):雙擊事件

onDoubleTapEvent(MotionEvent e):雙擊間隔中發生的動作。指觸發onDoubleTap以後,在雙擊之間發生的其它動作,包含down、up和move事件;下圖是雙擊一下的Log輸出:
技術分享

兩點總結:

1、從上圖可以看出,在第二下點擊時,先觸發OnDoubleTap,然後再觸發OnDown(第二次點擊)

2、其次在觸發OnDoubleTap以後,就開始觸發onDoubleTapEvent了,onDoubleTapEvent後面的數字代表了當前的事件,0指ACTION_DOWN,1指ACTION_UP,2 指ACTION_MOVE
在上一個例子的基礎上,我們再添加一個雙擊監聽類,實現如下:

[java] view plain copy
  1. public class MainActivity extends Activity implements OnTouchListener{
  2. private GestureDetector mGestureDetector;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. mGestureDetector = new GestureDetector(new gestureListener()); //使用派生自OnGestureListener
  8. mGestureDetector.setOnDoubleTapListener(new doubleTapListener());
  9. TextView tv = (TextView)findViewById(R.id.tv);
  10. tv.setOnTouchListener(this);
  11. tv.setFocusable(true);
  12. tv.setClickable(true);
  13. tv.setLongClickable(true);
  14. }
  15. /*
  16. * 在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector
  17. * 來分析是否有合適的callback函數來處理用戶的手勢
  18. */
  19. public boolean onTouch(View v, MotionEvent event) {
  20. return mGestureDetector.onTouchEvent(event);
  21. }
  22. //OnGestureListener監聽
  23. private class gestureListener implements GestureDetector.OnGestureListener{
  24. public boolean onDown(MotionEvent e) {
  25. Log.i("MyGesture", "onDown");
  26. Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();
  27. return false;
  28. }
  29. public void onShowPress(MotionEvent e) {
  30. Log.i("MyGesture", "onShowPress");
  31. Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();
  32. }
  33. public boolean onSingleTapUp(MotionEvent e) {
  34. Log.i("MyGesture", "onSingleTapUp");
  35. Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
  36. return true;
  37. }
  38. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  39. float distanceX, float distanceY) {
  40. Log.i("MyGesture22", "onScroll:"+(e2.getX()-e1.getX()) +" "+distanceX);
  41. Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();
  42. return true;
  43. }
  44. public void onLongPress(MotionEvent e) {
  45. Log.i("MyGesture", "onLongPress");
  46. Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();
  47. }
  48. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  49. float velocityY) {
  50. Log.i("MyGesture", "onFling");
  51. Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();
  52. return true;
  53. }
  54. };
  55. //OnDoubleTapListener監聽
  56. private class doubleTapListener implements GestureDetector.OnDoubleTapListener{
  57. public boolean onSingleTapConfirmed(MotionEvent e) {
  58. Log.i("MyGesture", "onSingleTapConfirmed");
  59. Toast.makeText(MainActivity.this, "onSingleTapConfirmed", Toast.LENGTH_LONG).show();
  60. return true;
  61. }
  62. public boolean onDoubleTap(MotionEvent e) {
  63. Log.i("MyGesture", "onDoubleTap");
  64. Toast.makeText(MainActivity.this, "onDoubleTap", Toast.LENGTH_LONG).show();
  65. return true;
  66. }
  67. public boolean onDoubleTapEvent(MotionEvent e) {
  68. Log.i("MyGesture", "onDoubleTapEvent");
  69. Toast.makeText(MainActivity.this, "onDoubleTapEvent", Toast.LENGTH_LONG).show();
  70. return true;
  71. }
  72. };
  73. }

雙擊一下,部分截圖如下:

技術分享

雙擊所對應的觸發事件順序:

技術分享

輕輕單擊一下,對應的事件觸發順序為:

技術分享

源碼在博客底部給出。

四、GestureDetector.SimpleOnGestureListener---類

它與前兩個不同的是:
1、這是一個類,在它基礎上新建類的話,要用extends派生而不是用implements繼承!
2、OnGestureListener和OnDoubleTapListener接口裏的函數都是強制必須重寫的,即使用不到也要重寫出來一個空函數但在SimpleOnGestureListener類的實例或派生類中不必如此,可以根據情況,用到哪個函數就重寫哪個函數,因為SimpleOnGestureListener類本身已經實現了這兩個接口的所有函數,只是裏面全是空的而已。

下面利用SimpleOnGestureListener類來重新實現上面的幾個效果,代碼如下:

[java] view plain copy
  1. public class MainActivity extends Activity implements OnTouchListener {
  2. private GestureDetector mGestureDetector;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. mGestureDetector = new GestureDetector(new simpleGestureListener());
  8. TextView tv = (TextView)findViewById(R.id.tv);
  9. tv.setOnTouchListener(this);
  10. tv.setFocusable(true);
  11. tv.setClickable(true);
  12. tv.setLongClickable(true);
  13. }
  14. public boolean onTouch(View v, MotionEvent event) {
  15. // TODO Auto-generated method stub
  16. return mGestureDetector.onTouchEvent(event);
  17. }
  18. private class simpleGestureListener extends
  19. GestureDetector.SimpleOnGestureListener {
  20. /*****OnGestureListener的函數*****/
  21. public boolean onDown(MotionEvent e) {
  22. Log.i("MyGesture", "onDown");
  23. Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT)
  24. .show();
  25. return false;
  26. }
  27. public void onShowPress(MotionEvent e) {
  28. Log.i("MyGesture", "onShowPress");
  29. Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT)
  30. .show();
  31. }
  32. public boolean onSingleTapUp(MotionEvent e) {
  33. Log.i("MyGesture", "onSingleTapUp");
  34. Toast.makeText(MainActivity.this, "onSingleTapUp",
  35. Toast.LENGTH_SHORT).show();
  36. return true;
  37. }
  38. public boolean onScroll(MotionEvent e1, MotionEvent e2,
  39. float distanceX, float distanceY) {
  40. Log.i("MyGesture", "onScroll:" + (e2.getX() - e1.getX()) + " "
  41. + distanceX);
  42. Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG)
  43. .show();
  44. return true;
  45. }
  46. public void onLongPress(MotionEvent e) {
  47. Log.i("MyGesture", "onLongPress");
  48. Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG)
  49. .show();
  50. }
  51. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  52. float velocityY) {
  53. Log.i("MyGesture", "onFling");
  54. Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG)
  55. .show();
  56. return true;
  57. }
  58. /*****OnDoubleTapListener的函數*****/
  59. public boolean onSingleTapConfirmed(MotionEvent e) {
  60. Log.i("MyGesture", "onSingleTapConfirmed");
  61. Toast.makeText(MainActivity.this, "onSingleTapConfirmed",
  62. Toast.LENGTH_LONG).show();
  63. return true;
  64. }
  65. public boolean onDoubleTap(MotionEvent e) {
  66. Log.i("MyGesture", "onDoubleTap");
  67. Toast.makeText(MainActivity.this, "onDoubleTap", Toast.LENGTH_LONG)
  68. .show();
  69. return true;
  70. }
  71. public boolean onDoubleTapEvent(MotionEvent e) {
  72. Log.i("MyGesture", "onDoubleTapEvent");
  73. Toast.makeText(MainActivity.this, "onDoubleTapEvent",
  74. Toast.LENGTH_LONG).show();
  75. return true;
  76. }
  77. }
  78. }


到此,有關GestureDetector的所有基礎知識都講解完了,下面給出一個小應用——識別用戶是向左滑還是向右滑!

源碼在博客底部給出。

五、OnFling應用——識別向左滑還是向右滑

這部分就有點意思了,可以說是上面知識的一個小應用,我們利用OnFling函數來識別當前用戶是在向左滑還是向右滑,從而打出日誌。先看下OnFling的參數:

[java] view plain copy
  1. boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
  2. 參數解釋:
  3. e1:第1個ACTION_DOWN MotionEvent
  4. e2:最後一個ACTION_MOVE MotionEvent
  5. velocityX:X軸上的移動速度,像素/秒
  6. velocityY:Y軸上的移動速度,像素/秒

首先,先說一下實現的功能:當用戶向左滑動距離超過100px,且滑動速度超過100 px/s時,即判斷為向左滑動;向右同理.代碼如下:

[java] view plain copy
  1. public class MainActivity extends Activity implements OnTouchListener {
  2. private GestureDetector mGestureDetector;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. mGestureDetector = new GestureDetector(new simpleGestureListener());
  8. TextView tv = (TextView)findViewById(R.id.tv);
  9. tv.setOnTouchListener(this);
  10. tv.setFocusable(true);
  11. tv.setClickable(true);
  12. tv.setLongClickable(true);
  13. }
  14. public boolean onTouch(View v, MotionEvent event) {
  15. // TODO Auto-generated method stub
  16. return mGestureDetector.onTouchEvent(event);
  17. }
  18. private class simpleGestureListener extends
  19. GestureDetector.SimpleOnGestureListener {
  20. /*****OnGestureListener的函數*****/
  21. final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
  22. // 觸發條件 :
  23. // X軸的坐標位移大於FLING_MIN_DISTANCE,且移動速度大於FLING_MIN_VELOCITY個像素/秒
  24. // 參數解釋:
  25. // e1:第1個ACTION_DOWN MotionEvent
  26. // e2:最後一個ACTION_MOVE MotionEvent
  27. // velocityX:X軸上的移動速度,像素/秒
  28. // velocityY:Y軸上的移動速度,像素/秒
  29. public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  30. float velocityY) {
  31. if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
  32. && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
  33. // Fling left
  34. Log.i("MyGesture", "Fling left");
  35. Toast.makeText(MainActivity.this, "Fling Left", Toast.LENGTH_SHORT).show();
  36. } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
  37. && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
  38. // Fling right
  39. Log.i("MyGesture", "Fling right");
  40. Toast.makeText(MainActivity.this, "Fling Right", Toast.LENGTH_SHORT).show();
  41. }
  42. return true;
  43. }
  44. }
  45. }

這段代碼難度不大,就不再細講,看下效果:
技術分享

源碼在博客底部給出。

源碼地址:http://download.csdn.net/detail/harvic880925/7978943

用戶手勢檢測-GestureDetector使用詳解