Android攻城狮GestureDetector和GestureOverlayView
生活随笔
收集整理的這篇文章主要介紹了
Android攻城狮GestureDetector和GestureOverlayView
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
手勢識別
可以通過以下兩種方式實現:
1. 使用GestureDetector
2. 使用GestureOverlayView(屬于線程的控件)手勢交互過程(原理):
1. 觸屏一剎那,觸發 MotionEvent 事件;
2. 被 OnTouchListener 監聽,在 onTouch()中獲得 MotionEvent對象;
3. GestureDetector 轉發 MotionEvent 對象至 OnGestureListener;
4. OnGestureListener 獲取該對象,根據該對象封裝的信息做出合適的反饋;MotionEvent:
1. 用于封裝手勢、觸摸筆、軌跡球等動作事件;
2. 內部封裝用于記錄橫軸和縱軸坐標的屬性X和Y。
GestureDetector:
識別各種手勢。
OnGestureListener:
1. 手勢交互的監聽接口,其提供多個抽象方法;
2. 根據 GestureDetector 的手勢識別結果,調用相應的方法。GestureDetector 詳解:
觸摸屏:按下、移動、抬起等。
監聽觸摸事件:重載 onTouch 或者設置 setOnTouchListener
GestureDetector 工作原理:
1. 當接收到用戶觸摸消息時,將消息交給 GestureDetector加工;
2. 通過設置監聽器獲得 GestureDetector 處理后的手勢。
GestureDetector提供兩個監聽器:
1. OnGestureListener:處理單擊類消息
2. OnDoubleTapListener:處理雙擊類消息
OnGestureListener接口的6個方法: 單擊:onDown(MotionEvent e) 抬起:onSingleTapUp(MotionEvent e) 短按:onShowPress(MotionEvent e) 長按:onLongPress(MotionEvent e) 滾動:onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float disanceY) 滑動:onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) (注解:velocity:速率,速度)OnDoubleTapListener接口的3個方法: 雙擊:onDoubleTap(MotionEvent e) 雙擊按下和抬起各觸發一次:onDoubleTapEvent(MotionEvent e) 單擊確認:onSingleTapConfirmed(MotionEvent e)就是很快地按下并抬起,但不連續點擊第二下。如果分別去實現這兩個接口的所有方法,未免太麻煩了,所以這里提供了另一個接口:SimpleOnGestureListener,它已經繼承了前面所講的兩個監聽器。 - 繼承SimpleOnGestureListener - 重載感興趣的手勢 1 public class MainActivity extends Activity { 2 ImageView imageView; 3 GestureDetector myDetector; 4 5 class myGestureListenner extends SimpleOnGestureListener { 6 @Override 7 // e1表示起始事件,e2表示末尾事件,每個事件都含有坐標屬性。通過起止事件的相對位置,可以判斷是從左往右滑動還是從右往左滑動。 8 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 9 float velocityY) { 10 // TODO Auto-generated method stub 11 if (e1.getX() - e2.getX() > 50) { 12 Toast.makeText(MainActivity.this, "從右邊往左邊滑動!", 0).show(); 13 14 } else if (e2.getX() - e1.getX() > 50) { 15 Toast.makeText(MainActivity.this, "從左邊往右邊滑動!", 0).show(); 16 } 17 return super.onFling(e1, e2, velocityX, velocityY); 18 } 19 20 } 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.fragment_main); 26 imageView = (ImageView) findViewById(R.id.image); 27 myDetector = new GestureDetector(new myGestureListenner()); 28 imageView.setOnTouchListener(new OnTouchListener() { 29 30 @Override 31 public boolean onTouch(View v, MotionEvent event) { 32 // TODO Auto-generated method stub 33 // 捕獲觸摸屏幕的Event事件 34 myDetector.onTouchEvent(event); 35 36 return true; 37 } 38 }); 39 } 40 41 }
OnGestureListener接口的6個方法: 單擊:onDown(MotionEvent e) 抬起:onSingleTapUp(MotionEvent e) 短按:onShowPress(MotionEvent e) 長按:onLongPress(MotionEvent e) 滾動:onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float disanceY) 滑動:onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) (注解:velocity:速率,速度)OnDoubleTapListener接口的3個方法: 雙擊:onDoubleTap(MotionEvent e) 雙擊按下和抬起各觸發一次:onDoubleTapEvent(MotionEvent e) 單擊確認:onSingleTapConfirmed(MotionEvent e)就是很快地按下并抬起,但不連續點擊第二下。如果分別去實現這兩個接口的所有方法,未免太麻煩了,所以這里提供了另一個接口:SimpleOnGestureListener,它已經繼承了前面所講的兩個監聽器。 - 繼承SimpleOnGestureListener - 重載感興趣的手勢 1 public class MainActivity extends Activity { 2 ImageView imageView; 3 GestureDetector myDetector; 4 5 class myGestureListenner extends SimpleOnGestureListener { 6 @Override 7 // e1表示起始事件,e2表示末尾事件,每個事件都含有坐標屬性。通過起止事件的相對位置,可以判斷是從左往右滑動還是從右往左滑動。 8 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 9 float velocityY) { 10 // TODO Auto-generated method stub 11 if (e1.getX() - e2.getX() > 50) { 12 Toast.makeText(MainActivity.this, "從右邊往左邊滑動!", 0).show(); 13 14 } else if (e2.getX() - e1.getX() > 50) { 15 Toast.makeText(MainActivity.this, "從左邊往右邊滑動!", 0).show(); 16 } 17 return super.onFling(e1, e2, velocityX, velocityY); 18 } 19 20 } 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.fragment_main); 26 imageView = (ImageView) findViewById(R.id.image); 27 myDetector = new GestureDetector(new myGestureListenner()); 28 imageView.setOnTouchListener(new OnTouchListener() { 29 30 @Override 31 public boolean onTouch(View v, MotionEvent event) { 32 // TODO Auto-generated method stub 33 // 捕獲觸摸屏幕的Event事件 34 myDetector.onTouchEvent(event); 35 36 return true; 37 } 38 }); 39 } 40 41 }
?
使用GestureOverlayView進行手勢識別的步驟: 1. 使用Gesture Builder生成手勢文件 2. 將文件加入到項目 3. 在項目中創建 GestureOverlayView,將它放置在想要識別手勢的控件上,或者把它包裹起來。只能識別文件中存在的手勢,如果不是文件中存在的手勢,就無法識別。 --------------- 在res文件夾下創建文件夾raw,把手勢文件gesture添加到這里。 GestureOverlayView 一種用于手勢輸入的透明覆蓋層,可覆蓋在其他控件的上方,也可以包含其他控件。存在3個監聽接口: GestureOverlayView.OnGestureListener // 手勢監聽器 GestureOverlayView.OnGesturePerformedListener // 手勢執行監聽器 GestureOverlayView.OnGesturingListener // 手勢執行中監聽器 ------------------ 如圖使用GestureOverlayView控件去包含ImageView控件。 可識別手勢的區域大小不是由ImageView決定,而是由GestureOverlayView決定。 ------------------------ 補充: 使用Android Studio則更加簡單,不用去創建 Simple Project。老師之所以要創建Simple Project,是因為模擬器中沒有Gesture Builder這種應用,所以要自己創建。而Android Studio的模擬器是有Gesture Builder的,所以我們可以直接進入模擬器,點擊Gesture Builder圖標,進行手勢的創建。 給gestureOverlayView設置監聽器: gestureOverlayView.addOnGesturePerformedListener(new OnGesturePerformedListener(){}) 重寫方法onGesturePerformed()。 如圖,onGesturePerformed()的示例代碼,也就是關于手勢識別的代碼實現。 ArrayList<Prediction>:預測集 predction.score:相似度,值越大,則越相似,也就是說你必須做出幾乎一模一樣的手勢才能通過識別。相似度的取值范圍一般是0.0~10.0,取10.0就已經太夸張了,因為很難做出非常接近的手勢。所以,這里的下限只取5.0: predction.score>=5.0 如果覺得顯示的手勢的軌跡不好看,可以自定義軌跡的樣式。 一些常見的XML屬性設置: Android:eventInterceptionEnabled 定義當手勢已經被識別出來時,是否攔截該手勢動作 Android:fadeDuration 當用戶畫完的時候,手勢效果淡出的時間 Android:fadeEnabled 用戶畫完之后,手勢是否自動淡出 Android:gestureColor 手勢的顏色 Android:gestureStrokeType 筆畫的類型 Android:gestureStrokeWidth 筆畫的粗細 1 public class MainActivity extends ActionBarActivity { 2 GestureOverlayView gestureOverlayView; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.fragment_main); 8 gestureOverlayView = (GestureOverlayView) findViewById(R.id.gestureOverlayView1); 9 // 1.找到預設定的手勢文件 10 // 2.加載那個手勢文件中的所有手勢 11 // 3.匹配,識別 12 13 // 從資源中將手勢庫文件加載進來 14 final GestureLibrary library = GestureLibraries.fromRawResource( 15 MainActivity.this, R.raw.gestures); 16 library.load(); 17 gestureOverlayView 18 .addOnGesturePerformedListener(new OnGesturePerformedListener() { 19 20 @Override 21 public void onGesturePerformed(GestureOverlayView overlay, 22 Gesture gesture) { 23 // TODO Auto-generated method stub 24 // 讀出手勢庫中內容 識別手勢 25 ArrayList<Prediction> mygesture = library 26 .recognize(gesture); 27 Prediction prediction = mygesture.get(0); 28 if (prediction.score >= 5.0) { 29 if (prediction.name.equals("exit")) { 30 finish(); 31 } 32 if (prediction.name.equals("next")) { 33 Toast.makeText(MainActivity.this, "下一首", 0) 34 .show(); 35 } 36 if (prediction.name.equals("previouse")) { 37 Toast.makeText(MainActivity.this, "上一首", 0) 38 .show(); 39 } 40 } else { 41 Toast.makeText(MainActivity.this, "沒有該手勢", 0) 42 .show(); 43 } 44 45 } 46 }); 47 48 } 49 50 }?
轉載于:https://www.cnblogs.com/my334420/p/6754432.html
總結
以上是生活随笔為你收集整理的Android攻城狮GestureDetector和GestureOverlayView的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue 单文件元件 — vTabs
- 下一篇: 一些Java面试题深入分析