android學習——GestureDetector.OnGestureListener 詳解

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. ????????setContentView(R.layout.main);??
  5. ????????TextView?tv?=?(TextView)?findViewById(R.id.tv);??
  6. ????????tv.setOnTouchListener(this);??
  7. ????}??
  8. ????public?boolean?onTouch(View?v,?MotionEvent?event)?{??
  9. ????????Toast.makeText(this,?"Touch?Touch",?Toast.LENGTH_SHORT).show();??
  10. ????????return?false;??
  11. ????}??
  12. }??

我們可以通過MotionEvent的getAction()方法來獲取Touch事件的類型,包括 ACTION_DOWN(按下觸摸屏), ACTION_MOVE(按下觸摸屏后移動受力點), ACTION_UP(松開觸摸屏)和ACTION_CANCEL(不會由用戶直接觸發)。借助對于用戶不同操作的判斷,結合getRawX()、getRawY()、getX()和getY()等方法來獲取坐標后,我們可以實現諸如拖動某一個按鈕,拖動滾動條等功能。

?

2. 回到今天的重點,當我們捕捉到Touch操作的時候,如何識別出用戶的Gesture?這里我們需要GestureDetector.OnGestureListener接口的幫助,代碼如下:

Java代碼?
  1. public?class?MyGesture?extends?Activity?implements?OnTouchListener,?OnGestureListener?{??
  2. ????private?GestureDetector?mGestureDetector;??
  3. ????public?MyGesture()?{??
  4. ????????mGestureDetector?=?new?GestureDetector(this);??
  5. ????}??
  6. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  7. ????????super.onCreate(savedInstanceState);??
  8. ????????setContentView(R.layout.main);??
  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. ????????mGestureDetector.setIsLongpressEnabled(true);??
  15. ????}??
  16. ??????
  17. ????/*?
  18. ?????*?在onTouch()方法中,我們調用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector?
  19. ?????*?來分析是否有合適的callback函數來處理用戶的手勢?
  20. ?????*/???
  21. ????public?boolean?onTouch(View?v,?MotionEvent?event)?{??
  22. ????????return?mGestureDetector.onTouchEvent(event);??
  23. ????}??
  24. ??
  25. ????//?用戶輕觸觸摸屏,由1個MotionEvent?ACTION_DOWN觸發??
  26. ????public?boolean?onDown(MotionEvent?arg0)?{??
  27. ????????Log.i("MyGesture",?"onDown");??
  28. ????????Toast.makeText(this,?"onDown",?Toast.LENGTH_SHORT).show();??
  29. ????????return?true;??
  30. ????}??
  31. ??????
  32. ????/*?
  33. ?????*?用戶輕觸觸摸屏,尚未松開或拖動,由一個1個MotionEvent?ACTION_DOWN觸發?
  34. ?????*?注意和onDown()的區別,強調的是沒有松開或者拖動的狀態?
  35. ?????*/??
  36. ????public?void?onShowPress(MotionEvent?e)?{??
  37. ????????Log.i("MyGesture",?"onShowPress");??
  38. ????????Toast.makeText(this,?"onShowPress",?Toast.LENGTH_SHORT).show();??
  39. ????}??
  40. ??????
  41. ????//?用戶(輕觸觸摸屏后)松開,由一個1個MotionEvent?ACTION_UP觸發??
  42. ????public?boolean?onSingleTapUp(MotionEvent?e)?{??
  43. ????????Log.i("MyGesture",?"onSingleTapUp");??
  44. ????????Toast.makeText(this,?"onSingleTapUp",?Toast.LENGTH_SHORT).show();??
  45. ????????return?true;??
  46. ????}??
  47. ??????
  48. ????//?用戶按下觸摸屏、快速移動后松開,由1個MotionEvent?ACTION_DOWN,?多個ACTION_MOVE,?1個ACTION_UP觸發??
  49. ????public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,?float?velocityY)?{??
  50. ????????Log.i("MyGesture",?"onFling");??
  51. ????????Toast.makeText(this,?"onFling",?Toast.LENGTH_LONG).show();??
  52. ????????return?true;??
  53. ????}??
  54. ??????
  55. ????//?用戶按下觸摸屏,并拖動,由1個MotionEvent?ACTION_DOWN,?多個ACTION_MOVE觸發??
  56. ????public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,?float?distanceX,?float?distanceY)?{??
  57. ????????Log.i("MyGesture",?"onScroll");??
  58. ????????Toast.makeText(this,?"onScroll",?Toast.LENGTH_LONG).show();??
  59. ????????return?true;??
  60. ????}??
  61. ??????
  62. ????//?用戶長按觸摸屏,由多個MotionEvent?ACTION_DOWN觸發??
  63. ????public?void?onLongPress(MotionEvent?e)?{??
  64. ????????Log.i("MyGesture",?"onLongPress");??
  65. ????????Toast.makeText(this,?"onLongPress",?Toast.LENGTH_LONG).show();??
  66. ????}??
  67. }??

?

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

Java代碼
  1. public?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軸上的移動速度,像素/秒??
  7. ??
  8. ????//?觸發條件?:??
  9. ????//?X軸的坐標位移大于FLING_MIN_DISTANCE,且移動速度大于FLING_MIN_VELOCITY個像素/秒??
  10. ??????
  11. ????final?int?FLING_MIN_DISTANCE?=?100,?FLING_MIN_VELOCITY?=?200;??
  12. ????if?(e1.getX()?-?e2.getX()?>?FLING_MIN_DISTANCE?&&?Math.abs(velocityX)?>?FLING_MIN_VELOCITY)?{??
  13. ????????//?Fling?left??
  14. ????????Log.i("MyGesture",?"Fling?left");??
  15. ????????Toast.makeText(this,?"Fling?Left",?Toast.LENGTH_SHORT).show();??
  16. ????}?else?if?(e2.getX()?-?e1.getX()?>?FLING_MIN_DISTANCE?&&?Math.abs(velocityX)?>?FLING_MIN_VELOCITY)?{??
  17. ????????//?Fling?right??
  18. ????????Log.i("MyGesture",?"Fling?right");??
  19. ????????Toast.makeText(this,?"Fling?Right",?Toast.LENGTH_SHORT).show();??
  20. ????}??
  21. ????return?false;??
  22. }??

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

?

4. SimpleOnGestureListener

Java代碼
  1. public?class?MyGesture?extends?Activity?implements?OnTouchListener?{ ??
  2. ????private?GestureDetector?mGestureDetector; ??
  3. ????public?MyGesture()?{ ??
  4. ????????mGestureDetector?=?new?GestureDetector(new?MySimpleGesture()); ??
  5. ????} ??
  6. ????public?void?onCreate(Bundle?savedInstanceState)?{ ??
  7. ????????super.onCreate(savedInstanceState); ??
  8. ????????setContentView(R.layout.main); ??
  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. ????public?boolean?onTouch(View?v,?MotionEvent?event)?{ ??
  16. ????????if?(event.getAction()?==?MotionEvent.ACTION_UP)?{ ??
  17. ????????????Log.i("MyGesture",?"MotionEvent.ACTION_UP"); ??
  18. ????????} ??
  19. ????????return?mGestureDetector.onTouchEvent(event); ??
  20. ????} ??
  21. ???? ??
  22. ????//?SimpleOnGestureListener?implements?GestureDetector.OnDoubleTapListener,?GestureDetector.OnGestureListener??
  23. ????private?class?MySimpleGesture?extends?SimpleOnGestureListener?{ ??
  24. ????????//?雙擊的第二下Touch?down時觸發????
  25. ????????public?boolean?onDoubleTap(MotionEvent?e)?{ ??
  26. ????????????Log.i("MyGesture",?"onDoubleTap"); ??
  27. ????????????return?super.onDoubleTap(e); ??
  28. ????????} ??
  29. ???????? ??
  30. ????????//?雙擊的第二下Touch?down和up都會觸發,可用e.getAction()區分???
  31. ????????public?boolean?onDoubleTapEvent(MotionEvent?e)?{ ??
  32. ????????????Log.i("MyGesture",?"onDoubleTapEvent"); ??
  33. ????????????return?super.onDoubleTapEvent(e); ??
  34. ????????} ??
  35. ???????? ??
  36. ????????//?Touch?down時觸發????
  37. ????????public?boolean?onDown(MotionEvent?e)?{ ??
  38. ????????????Log.i("MyGesture",?"onDown"); ??
  39. ????????????return?super.onDown(e); ??
  40. ????????} ??
  41. ???????? ??
  42. ????????//?Touch了滑動一點距離后,up時觸發???
  43. ????????public?boolean?onFling(MotionEvent?e1,?MotionEvent?e2,?float?velocityX,?float?velocityY)?{ ??
  44. ????????????Log.i("MyGesture",?"onFling"); ??
  45. ????????????return?super.onFling(e1,?e2,?velocityX,?velocityY); ??
  46. ????????} ??
  47. ???????? ??
  48. ????????//?Touch了不移動一直Touch?down時觸發???
  49. ????????public?void?onLongPress(MotionEvent?e)?{ ??
  50. ????????????Log.i("MyGesture",?"onLongPress"); ??
  51. ????????????super.onLongPress(e); ??
  52. ????????} ??
  53. ???????? ??
  54. ????????//?Touch了滑動時觸發???
  55. ????????public?boolean?onScroll(MotionEvent?e1,?MotionEvent?e2,?float?distanceX,?float?distanceY)?{ ??
  56. ????????????Log.i("MyGesture",?"onScroll"); ??
  57. ????????????return?super.onScroll(e1,?e2,?distanceX,?distanceY); ??
  58. ????????} ??
  59. ???????? ??
  60. ????????/*??
  61. ?????????*?Touch了還沒有滑動時觸發??
  62. ?????????*?(1)onDown只要Touch?Down一定立刻觸發??
  63. ?????????*?(2)Touch?Down后過一會沒有滑動先觸發onShowPress再觸發onLongPress??
  64. ?????????*?So:?Touch?Down后一直不滑動,onDown?->?onShowPress?->?onLongPress這個順序觸發。??
  65. ?????????*/??
  66. ????????public?void?onShowPress(MotionEvent?e)?{ ??
  67. ????????????Log.i("MyGesture",?"onShowPress"); ??
  68. ????????????super.onShowPress(e); ??
  69. ????????} ??
  70. ??
  71. ????????/*??
  72. ?????????*?兩個函數都是在Touch?Down后又沒有滑動(onScroll),又沒有長按(onLongPress),然后Touch?Up時觸發??
  73. ?????????*?點擊一下非常快的(不滑動)Touch?Up:?onDown->onSingleTapUp->onSingleTapConfirmed??
  74. ?????????*?點擊一下稍微慢點的(不滑動)Touch?Up:?onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed???
  75. ?????????*/? ??
  76. ????????public?boolean?onSingleTapConfirmed(MotionEvent?e)?{ ??
  77. ????????????Log.i("MyGesture",?"onSingleTapConfirmed"); ??
  78. ????????????return?super.onSingleTapConfirmed(e); ??
  79. ????????} ??
  80. ????????public?boolean?onSingleTapUp(MotionEvent?e)?{ ??
  81. ????????????Log.i("MyGesture",?"onSingleTapUp"); ??
  82. ????????????return?super.onSingleTapUp(e); ??
  83. ????????} ??
  84. ????} ??
  85. }

轉載于:https://www.cnblogs.com/Free-Thinker/p/4040957.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/375549.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/375549.shtml
英文地址,請注明出處:http://en.pswp.cn/news/375549.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于安卓一鍵分享的,急求幫助!

問題描述現在要做一個項目,設置里面點擊一個按鈕就可以分享,有三個分享平臺,新浪微博,微信和微信朋友圈現在的問題是我要在三個平臺分享的內容不同,在新浪微博中分享的是一段文字敘述和一個網頁鏈接;而在微…

和可被 K 整除的子數組

給定一個整數數組 A,返回其中元素之和可被 K 整除的(連續、非空)子數組的數目。 示例: 輸入:A [4,5,0,-2,-3,1], K 5 輸出:7 解釋: 有 7 個子數組滿足其元素之和可被 K 5 整除:…

前端進階路線圖

CSS不能編程?用Less、Sass、Stylus、甚至直接用 Absurd,框架除了Bootstrap還有很多。JS寫多了很麻煩?jQuery。移動開發?Zepto.js。結構不好?找框架,Backbone.js是MVC,AngularJS和Ember.js是MVVM…

流媒體直播服務LSS

流媒體直播服務LSS posted on 2014-10-22 11:23 實驗室 閱讀(...) 評論(...) 編輯 收藏 轉載于:https://www.cnblogs.com/labs/p/4042641.html

Win7安裝vs2010失敗

提示: --------------------------------------------------------------------------------------------------------------------------------------- 解決方法:開始運行中regedit打開注冊表找到HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control …

調光設備術語:調光曲線(轉)

源:調光設備術語:調光曲線 核心提示:調光曲線是調光設備重要的參數之一,它直接影響到了燈光輸出的效果,是數字化調光設備性能的體現。上面這句話包含了三點內容,我們逐條解析。 調光曲線是調光設備重要的參…

深入淺出理解QTimeLine類

網上找了下QTimeLIne類的介紹,要么就是代碼一貼自己看去,要么就是說不到重點,正巧自己項目遇到這個類,在這里寫一下,給需要的同學看下。 因為我最近需要有動畫方面配合時間間隔觸發QGraphicsView框架的需求&#xff0c…

0909編譯原理

1.編譯原理學什么? 編譯原理是計算機專業的一門重要專業課,旨在介紹編譯程序構造的一般原理和基本方法。內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成。 2.為什么學編譯原理? 這門…

何為動態綁定(轉)

動態綁定只是叫法不同,你可以理解為多態!例如,有一個抽像fruit水果父類,其中定義了一個方法抽像eat方法,而apple繼承fruit并實現fruit的eat方法,而banana繼承fruit并實現fruit的eat方法,外部調用…

繼承與多態

第十七講 A)構造方法的重載:只需看參數即可。如果想在一個構造方法中調用另外一個構造方法,那么可以用this()的方式調用,this()括號中的參數表示目標構造方法的參數。this()必須要作為構造方法的第一條語句。 B)繼承&a…

c++學習心得

c是大一開始接觸的一門新的語言,說老實話當時學的并不好興趣指數5顆星中只有3顆。但是既然是學這方面的,還是好好聽課學習吧。下面簡單的說一下c的一些學習心得吧! c是什么?c是一種面向對象的程序設計語言。c是c的一種提高&#x…

實現strstr()

實現 strStr() 函數。 給定一個 haystack 字符串和一個 needle 字符串,在 haystack 字符串中找出 needle 字符串出現的第一個位置 (從0開始)。如果不存在,則返回 -1。 示例 1: 輸入: haystack "hello", needle "ll" 輸出: 2示例…

有效電話號碼

給定一個包含電話號碼列表(一行一個電話號碼)的文本文件 file.txt,寫一個 bash 腳本輸出所有有效的電話號碼。 你可以假設一個有效的電話號碼必須滿足以下兩種格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一個數字…

JSP中RequestDispatcher的用法

RequestDispatcher是一個Web資源的包裝器&#xff0c;可以用來把當前request傳遞到該資源&#xff0c;或者把新的資源包括到當前響應中。RequestDispatcher接口中定義了兩個方法&#xff1a;include/forward 由于<jsp:include>只能指定固定的jsp文件名&#xff0c;不能動…

TCP/IP三次握手與四次握手

原文地址 http://blog.csdn.net/whuslei/article/details/6667471 http://blog.csdn.net/wo2niliye/article/details/48447933 建立TCP需要三次握手才能建立&#xff0c;而斷開連接則需要四次握手。整個過程如下圖所示&#xff1a; 先來看看如何建立連接的。 首先Client端發送連…

vim支持nginx語法高亮

下載nginx源碼&#xff0c;解壓之后&#xff0c;將contribu/vim/*拷貝到~/.vim/目錄&#xff0c;如果沒有~/.vim/目錄&#xff0c;則創建即可。 cp -r contrib/vim/* ~/.vim/或 mkdir -p ~/.vim/ cp -r contrib/vim/* ~/.vim/此時再打開conf/nginx.conf就可以看到已經語法高亮…

Delphi 正則表達式語法(4): 常用轉義字符與 .

Delphi 正則表達式語法(4): 常用轉義字符與 . // \d 匹配所有數字, 相當于 [0-9] varreg: TPerlRegEx; beginreg : TPerlRegEx.Create(nil);reg.Subject : 期待Delphi 2008 for Win32&#xff01;;reg.RegEx : \d;reg.Replacement : ◆;reg.ReplaceAll;ShowMessage(reg.Subje…

C語言操作mysql

php中 mysqli, pdo 可以用 mysqlnd 或 libmysqlclient 實現 前者 從 php 5.3.0起已內置到php中, 并且支持更多的特性&#xff0c;推薦用 mysqlnd mysqlnd &#xff0c; libmysqlclient 對比&#xff1a;http://php.net/manual/en/mysqlinfo.library.choosing.php mysqlnd 目前是…

Hadoop DistributedCache分布式緩存的使用

轉載請注明&#xff1a;http://www.cnblogs.com/demievil/p/4059141.html 我的github博客&#xff1a;http://demievil.github.io/ 做項目的時候遇到一個問題&#xff0c;在Mapper和Reducer方法中處理目標數據時&#xff0c;先要去檢索和匹配一個已存在的標簽庫&#xff0c;再對…

每日溫度

根據每日 氣溫 列表&#xff0c;請重新生成一個列表&#xff0c;對應位置的輸出是需要再等待多久溫度才會升高超過該日的天數。如果之后都不會升高&#xff0c;請在該位置用 0 來代替。 例如&#xff0c;給定一個列表 temperatures [73, 74, 75, 71, 69, 72, 76, 73]&#xf…