Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 觸摸手勢(來自官方文檔)

Android 觸摸手勢(來自官方文檔)

編輯:關於Android編程

Detecting Common Gestures,一般分為兩個階段:

一: Gathering data about touch events.(收集數據)

二: Interpreting the data to see if it meets the criteria for any of the gestures your app supports.(根據自己需要使用檢測到的數據)

本文主要涉及到 GestureDetectorCompat 和 MotionEventCompat 兩個類,這兩個類在 Support Library中,Support Library classes 可以支持在API 1.6版本 以上使用.

另外,關於 MotionEvent 和MotionEventCompat: 和MotionEventCompat不是MotionEvent的替代,它僅僅提供了一些靜態方法,

Note that MotionEventCompat is not a replacement for the MotionEvent class. Rather, it provides static utility methods to which you pass your MotionEvent object in order to receive the desired action associated with that event

Gather Data

當手指觸摸屏幕時,就會觸發 onTouchEvent() 方法,作為一個 系統任務 接收觸摸事件,
當最後一個手指離開時,結束 gesture ,並把 MotionEvent 傳遞給onTouchEvent(),這樣就可以
根據需要使用MotionEvent提供的詳細測量數據.

在Activity 或者View中獲取觸摸事件

為了截獲touch事件,你需要覆寫Activity或View的onTouchEvent方法

下面是一個在Activity中,獲取觸摸事件的示例:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // This example shows an Activity, but you would use the same approach if
    // you were subclassing a View.
    @Override
    public boolean onTouchEvent(MotionEvent event) {
          final String DEBUG_TAG = "Gestures";

        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);
        }


    }
}

如圖:

這裡寫圖片描述

接下來看看在View中如何獲取觸摸事件呢:

在view中,你可以使用 setOnTouchListener() 方法依附於任何一個 實現了 View.OnTouchListener 接口的對象.這樣就可以不繼承View而處理點擊事件

public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = (TextView) findViewById(R.id.tv);
        textView.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        // ... Respond to touch events
        final String DEBUG_TAG = "Gestures";

        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);
        }
    }
}

運行後如圖:

這裡寫圖片描述

可以看出,當點擊TextView時,會相應不同的觸摸事件.而點擊TextView以外的部分則不會.

注意:創建Listener的時候,對於ACTION_DOWN 如果返回的是 false,listener將不會調用 ACTION_MOVE 和ACTION_UP 等事件,這是因為ACTION_DOWN 是所有觸摸事件的開始

當然,如果你創建一個自定義的View,你可以重寫 上面的 onTouchEvent() 方法.<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMiBpZD0="detect-gestures檢測手勢">Detect Gestures(檢測手勢)

Android提供了GestureDetector 類來檢測一般的手勢。

Detecting All Supported Gestures

 1.生成GestureDetector 對象(或GestureDetectorCompat對象),構造時的參數傳入監聽器對象。

  監聽器對象實現GestureDetector.OnGestureListener 接口。當一個觸摸事件發生的時候,接口 GestureDetector.OnGestureListener 就會通知用戶.

為了讓 GestureDetector對象接收到事件,需要覆寫View或Activity中的 onTouchEvent()方法,將事件傳遞給detector對象。

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
    private static final String DEBUG_TAG = "Gestures";
    private GestureDetector mDetector;

    @Override
    protected 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 GestureDetector(this, this);
        // Set the gesture detector as the double tap
        // listener.
        mDetector.setOnDoubleTapListener(this);


    }

//為了讓 GestureDetector對象接收到事件,需要覆寫View或Activity中的 onTouchEvent()方法,將事件傳遞給detector對象
    @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 void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress:-------------- " + 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 onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress:-------------- " + event.toString());
    }

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

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed:-------------- " + event.toString());
        return true;
    }
    @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;
    }
}
實現 GestureDetector.OnGestureListener 接口需要重寫一下抽象方法

這裡寫圖片描述
* 實現 GestureDetector.OnDoubleTapListener 接口需要重寫以下方法:

這裡寫圖片描述

上述方法,返回值為 ture 表明攔截該事件,反而言之,返回false表明不攔截,事件繼續傳遞.

通過上面的實例,在實際操作之後,你就會明白 你的一次屏幕觸摸竟會怎樣引起一個相互作用的MotionEvent事件,你的一次簡單的觸摸會引起怎樣的復雜的 事件交互.

GestureDetector.SimpleOnGestureListener類

如果你僅僅是想利用其中的一些手勢而不是全部,那麼你可以選擇繼承GestureDetector.SimpleOnGestureListener類,這是一個適配器模式,即這個類實現了GestureDetector.OnGestureListener 接口,為其中所有的方法提供了空實現(返回值都是false),當繼承GestureDetector.SimpleOnGestureListener類時,子類只需要覆寫感興趣的方法,其他方法是空實現。

下面這個實例,創建了一個內部類繼承了 GestureDetector.SimpleOnGestureListener ,並且選擇性的重寫了 GestureDetector.SimpleOnGestureListener 的 onDown() 和 onFling() 方法

public class MainActivity extends AppCompatActivity{
    private static final String DEBUG_TAG = "Gestures";
    private GestureDetectorCompat mGesture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGesture = new GestureDetectorCompat(this,new MyGestureListener());

    }

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

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener{

        //選擇性的重寫 GestureDetector.SimpleOnGestureListener 的方法
        @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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved