Android 手势操作GestureDetector
在很多應用中我們經常會看到一些不同手勢的點擊事件,例如QQ的消息列表,我們可以通過左滑消息來選擇刪除或者置頂或者標記為已讀,我們也可以通過右滑拖出QQ菜單。有些應用中還會有長按,雙擊等手勢。但是一般情況下,這些操作的手勢都不是很復雜,不會出現什么右擊左擊,或者三連擊這樣的手勢。因為開發應用的原則就是簡單化,讓別人可以一看就懂,一看就會。
今天我們就來學習一下Android中手勢的操作。在Android中手勢的操作使用GestureDetector這個類。
GestureDetector概述
Detects various gestures and events using the supplied MotionEvents. The GestureDetector.OnGestureListener callback will notify users when a particular motion event has occurred. This class should only be used with MotionEvents reported via touch (don’t use for trackball events).
GestureDetector通過MotionEvent類檢測不同的手勢和事件。在MotionEvent有很多基礎的動作監測:ACTION_CANCEL(動作取消), ACTION_DOWN(按下), ACTION_MOVE(移動),ACTION_UP(抬起)等,而手勢的操作就是以MotionEvent中這些基本的動作為基礎的,通過將這些基本的動作組合從而形成手勢。在GestureDetector中有一個GestureDetector.OnGestureListener監聽類,這個類都是當手勢發生時調用的。
要使用GestureDetector類,我們首先要創建它的對象,我們先來看他的構造器:
注意:GestureDetector(GestureDetector.OnGestureListener listener, Handler handler)和GestureDetector(GestureDetector.OnGestureListener listener)在API level 3以后已經取代,這里不再列出。
- GestureDetector(Context context, GestureDetector.OnGestureListener listener)
傳入兩個參數,一個是Context的對象,一個是GestureDetector.OnGestureListener的對象。上面已經講過GestureDetector.OnGestureListener是什么。 - GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler)
前兩個不用說了,第三個我查了一下API,原文是這樣:”the handler to use for running deferred listener events.”,意思應該是當運行延時的監聽對象時使用這個Handler對象。 - GestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused)
前三個不用說了吧,最后一個是定義當前有沒有被使用。
一般情況下我們都是使用第一個構造器。
GestureDetector中的方法不是很多,有兩個是非常重要的,我們這里拿出來說一說,其他的看名字就了解如何使用了: - onGenericMotionEvent(MotionEvent ev)
當我們的手勢動作是由GenericMotionEvent動作構成時,我們需要調用這個方法,這樣我們定義的手勢才可用。 onTouchEvent(MotionEvent ev)
當我們的手勢是由MotionEvent 構成時,我們需要調用這個方法,手勢才能生效。我們下面來看一下GestureDetector手勢是如何定義的?
GestureDetector.SimpleOnGestureListener
創建手勢,首先要創建一個GestureDetector對象。創建GestureDetector對象時要傳入一個GestureDetector.OnGestureListener對象,所以我們要創建一個GestureDetector.OnGestureListener對象,但是GestureDetector.OnGestureListener是一個interface接口,有人可能會想我們可以創建一個GestureDetector.OnGestureListener的匿名內部類啊,這樣是可以,但是要實現GestureDetector.OnGestureListener中的好多方法,這樣會使我們代碼冗長復雜。API中給我們提供了一個解決的方法,就是通過使用GestureDetector.SimpleOnGestureListener類。
我們看API中對他的描述:A convenience class to extend when you only want to listen for a subset of all the gestures. This implements all methods in the GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, and GestureDetector.OnContextClickListener but does nothing and return false for all applicable methods.
大體意思是這樣的:我們可以通過使用這個類來監聽一系列的手勢操作,也就是我們可以使用這二個監聽器監聽多個手勢,這個類繼承了: GestureDetector.OnGestureListener(手勢監聽器), GestureDetector.OnDoubleTapListener(雙擊監聽器), and GestureDetector.OnContextClickListener(上下文點擊監聽器)中的所有方法。
我們來看一下他的方法:
onContextClick(MotionEvent e):上下文點擊手勢。
onDoubleTap(MotionEvent e):雙擊手勢。
onDoubleTapEvent(MotionEvent e):雙擊按下和抬起分別產生點擊事件手勢。
onDown(MotionEvent e):單擊手勢。
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手勢,這個要與onScroll區別:onFling是滑動后,事件響應;onScroll是手指滑動時,控件也跟著滑動,同時響應。
onLongPress(MotionEvent e):長按手勢。
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):拖動手勢。
onShowPress(MotionEvent e):按下時響應事件。
onSingleTapConfirmed(MotionEvent e):單擊手勢。
onSingleTapUp(MotionEvent e):也是單擊手勢,是單擊抬起后響應時間。
手勢定義
前面基礎差不多都打好了,下面我們來使用下。這里只練習:雙擊,滑動和拖動的手勢操作。
手勢定義 ###
定義一個MyButton類繼承Button控件。
public class MyButton extends Button {private GestureDetector mGestureDetector;//定義手勢對象//自定義View的構造器public MyButton(Context context) {super(context);}public MyButton(Context context, AttributeSet attrs) {super(context, attrs);//初始化GestureDetector對象,傳入GestureDetector.SimpleOnGestureListener對象,監聽多個手勢。mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {//監聽雙擊手勢@Overridepublic boolean onDoubleTap(MotionEvent e) { Log.d("data", "點擊了兩次按鈕! ");return true;}//監聽滑動手勢@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {if (Math.abs(e2.getX() - e1.getX()) > 0) {//設置控件滑動的動畫ObjectAnimator.ofFloat(MyButton.this, "translationX", getTranslationX(), getTranslationX() + (e2.getX() - e1.getX())).setDuration(500).start();return true;}return super.onFling(e1, e2, velocityX, velocityY);}//監聽拖動的手勢@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {//設置控件跟隨手勢移動setTranslationY(getTranslationY() + e2.getY() - e1.getY());setTranslationX(getTranslationX() + e2.getX() - e1.getX());return true;}});}@Overridepublic boolean onTouchEvent(MotionEvent event) {//調用此方法,實現手勢的監聽使用。mGestureDetector.onTouchEvent(event);return super.onTouchEvent(event);} } 注意:復制代碼使用時,onFling方法和onScroll方法不要同時使用,因為效果近似,可能會看不出效果來。使用onFling手勢將onScroll方法屏蔽掉,使用onScroll手勢時同理。
雙擊手勢:
滑動手勢:
拖動手勢:
Activity中響應手勢事件
如果我們想在Activity中使用雙擊,滑動,拖動的點擊事件,我們需要在MyButton中定義一個點擊事件。這里我們以雙擊為例,在MyButton中添加如下代碼:(這里使用到了自定義View中的自定義點擊事件知識點,不懂的可以查看《Android 自定義View——自定義點擊事件 》這篇博客。)
//這里其實是使用的自定義View的點擊事件public OnDoubleClickListerner onDoubleClickListerner;//定義雙擊的監聽接口對象//設置獲得雙擊的監聽接口對象的set方法。public void setOnDoubleClickListerner(OnDoubleClickListerner onDoubleClickListerner) {this.onDoubleClickListerner = onDoubleClickListerner;}//創建雙擊的監聽接口interface OnDoubleClickListerner {void onDoubleClick(View view);}在雙擊手勢中添加:
//監聽雙擊手勢@Overridepublic boolean onDoubleTap(MotionEvent e) {if (onDoubleClickListerner != null) {onDoubleClickListerner.onDoubleClick(MyButton.this);}Log.d("data", "點擊了兩次按鈕! ");return true;}這樣我們就可以在Activity中使用了:
public class MainActivity extends AppCompatActivity {private MyButton button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (MyButton) findViewById(R.id.button);button.setOnDoubleClickListerner(new MyButton.OnDoubleClickListerner() {@Overridepublic void onDoubleClick(View view) {Log.d("data", "點擊了兩次按鈕! ");//次此處添加處理代碼}});} }總結
以上是生活随笔為你收集整理的Android 手势操作GestureDetector的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3月9日—3月13日四年级课程表
- 下一篇: React Native Android