Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 觸摸及手勢操作GestureDetector

Android 觸摸及手勢操作GestureDetector

編輯:關於Android編程

 

現在的智能手機不敢說百分百的都是觸摸屏,也應該是百分之九九以上為觸摸屏了,觸摸屏為我們操作無鍵盤、無鼠標的手機系統帶來了很多的便利。當用戶觸摸屏幕時會產生很多的觸摸事件,down、up、move等等。View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)方法,我們可以處理一些touch事件,如下:

 

public class MainActivity extends Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){ 

    int action = MotionEventCompat.getActionMasked(event);

    switch(action) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,Action was DOWN);
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,Action was MOVE);
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,Action was UP);
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,Action was CANCEL);
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,Movement occurred outside bounds  +
                    of current screen element);
            return true;      
        default : 
            return super.onTouchEvent(event);
    }      
}


 

OnTouch提供的事件還是相對較簡單,如果需要處理一些復雜的手勢,用這個接口就會很麻煩,因為我們要根據用戶觸摸的軌跡去判斷是什麼手勢。Android sdk給我們提供了GestureDetector(Gesture:手勢Detector:識別)類,通過這個類我們可以識別很多的手勢。

 

public class GestureDetector extends Object

java.lang.Object

android.view.GestureDetector

GestureDetector屬於android.view包,android還提供了android.gesture包支持更多的手勢操作,以後我們會介紹到。官方的介紹中使用了GestureDetectorCompat處理手勢識別,為什麼使用GestureDetectorCompat替換了GestureDetector呢,官方的是這樣解釋的:

\

 

GestureDetectorCompat實例化有下面兩種方法:

\

 

GestureDetector類對外提供了兩個接口:OnGestureListener,OnDoubleTapListener,還有一個內部類SimpleOnGestureListener;SimpleOnGestureListener類是GestureDetector提供給我們的一個更方便的響應不同手勢的類,它實現了上述兩個接口,該類是static class,也就是說它實際上是一個外部類,我們可以在外部繼承這個類,重寫裡面的手勢處理方法。因此實現手勢識別有兩種方法,一種實現OnGestureListener接口,另一種是使用SimpleOnGestureListener類。

OnGestureListener有下面的幾個動作:

按下(onDown): 剛剛手指接觸到觸摸屏的那一剎那,就是觸的那一下。

 

拋擲(onFling): 手指在觸摸屏上迅速移動,並松開的動作。

 

長按(onLongPress): 手指按在持續一段時間,並且沒有松開。

 

滾動(onScroll): 手指在觸摸屏上滑動。

 

按住(onShowPress): 手指按在觸摸屏上,它的時間范圍在按下起效,在長按之前。

 

抬起(onSingleTapUp):手指離開觸摸屏的那一剎那。

 

使用OnGestureListener接口,這樣需要重載OnGestureListener接口所有的方法,適合監聽所有的手勢,正如官方文檔提到的“Detecing All Supported Gestures”。

 

public class MainActivity extends Activity implements 
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{

    private static final String DEBUG_TAG = Gestures;
    private GestureDetectorCompat mDetector; 

    // Called when the activity is first created. 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener
        mDetector = new GestureDetectorCompat(this,this);
        // Set the gesture detector as the double tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
    }

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
        this.mDetector.onTouchEvent(event);
        // Be sure to call the superclass implementation
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) { 
        Log.d(DEBUG_TAG,onDown:  + event.toString()); 
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2, 
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, onFling:  + event1.toString()+event2.toString());
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, onLongPress:  + event.toString()); 
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        Log.d(DEBUG_TAG, onScroll:  + e1.toString()+e2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, onShowPress:  + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, onSingleTapUp:  + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, onDoubleTap:  + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, onDoubleTapEvent:  + event.toString());
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, onSingleTapConfirmed:  + event.toString());
        return true;
    }
}


這樣會造成有些手勢動作我們用不到,但是還要重載。SimpleOnGestureListener類的出現為我們解決了這個問題,如果你想“Detecting a Subset of Supported Gestures”,SimpleOnGestureListener是最好的選擇。

 

 

public class MainActivity extends Activity { 

    private GestureDetectorCompat mDetector; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
    }

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
        this.mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = Gestures; 

        @Override
        public boolean onDown(MotionEvent event) { 
            Log.d(DEBUG_TAG,onDown:  + event.toString()); 
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, onFling:  + event1.toString()+event2.toString());
            return true;
        }
    }
}


 

最後了我們也解釋兩個問題:

1、onTouchEvent中為什麼使用了MotionEventCompat,而不直接使用MotionEvent。因為MotionEventCompat使更多的Action適配到API 4。

2、Android的view怎麼使用手勢,方法如下:

 

 View myView = findViewById(R.id.my_view); 
        myView.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                // ... Respond to touch events       
                this.mDetector.onTouchEvent(event);
                return super.onTouchEvent(event);
            }
        });

 

 

 

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