前言
- 手勢識別在
Android
開發的應用非常常見 - 今天
carson
將詳細給大家講解Android
手勢識別類:GestureDetector
類的使用。(含實例講解)
目錄
簡介
下面,我將結合實例,詳細介紹GestureDetector的使用接口 & 使用類。
接口1:OnGestureListener
1. 作用
檢測用戶在屏幕的以下操作:按下瞬間、按壓、長按、輕擊、快速滑屏、拖動
2. 使用步驟
// 步驟1:創建手勢檢測器實例 & 傳入OnGestureListener接口(需要複寫對應方法)
// 構造函數有3個,常用的是第二個
// 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
// 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
// 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
});
// 步驟2-1:讓某個View檢測手勢 - 重寫View的onTouch函數,將View的觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
View.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true; // 注:返回true才能完整接收觸摸事件
}
});
// 步驟2-2:讓某個Activity檢測手勢:重寫Activity的dispatchTouchEvent函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mGestureDetector.onTouchEvent(ev); // 讓GestureDetector響應觸碰事件
super.dispatchTouchEvent(ev); // 讓Activity響應觸碰事件
return false;
}
3. 實例說明
現在對一個TextView進行手勢檢測
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:text="carson_ho Test"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView mTextView;
GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 步驟1:創建手勢檢測器實例 & 傳入OnGestureListener接口(需要複寫對應方法)
mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
});
// 步驟2:讓TextView檢測手勢:重寫View的onTouch函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
mTextView = (TextView) findViewById(R.id.textView);
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return false;
}
});
}
}
4. 示意圖
我在屏幕作出一系列手勢進行測試
接口2:OnDoubleTapListener
1. 作用
檢測用戶單擊、雙擊屏幕
2. 使用步驟
// 步驟1:創建手勢檢測器實例
// 注:使用OnDoubleTapListener接口時,需要使用GestureDetector,而GestureDetector的創建則必須傳入OnGestureListener接口
// 所以在使用OnDoubleTapListener接口時,也必須實現OnGestureListener接口
// 構造函數有3個,常用的是第二個
// 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
// 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
// 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
});
// 步驟2:創建 & 設置OnDoubleTapListener接口實現類
mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
// 1. 單擊事件
// 關於OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的區別
// onSingleTapConfirmed:再次點擊(即雙擊),則不會執行
// onSingleTapUp:手擡起就會執行
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("MyGesture", "onSingleTapConfirmed");
return false;
}
// 2. 雙擊事件
public boolean onDoubleTap(MotionEvent e) {
Log.i("MyGesture", "onDoubleTap");
return false;
}
// 3. 雙擊間隔中發生的動作
// 指觸發onDoubleTap後,在雙擊之間發生的其它動作,包含down、up和move事件;
public boolean onDoubleTapEvent(MotionEvent e) {
Log.i("MyGesture", "onDoubleTapEvent");
return false;
}
});
// 步驟3-1:讓某個View檢測手勢 - 重寫View的onTouch函數,將View的觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
View.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true; // 注:返回true才能完整接收觸摸事件
}
});
// 步驟3-2:讓某個Activity檢測手勢:重寫Activity的dispatchTouchEvent函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mGestureDetector.onTouchEvent(ev); // 讓GestureDetector響應觸碰事件
super.dispatchTouchEvent(ev); // 讓Activity響應觸碰事件
return false;
}
3. 實例說明
現在對一個TextView進行手勢檢測
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:text="carson_ho Test"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView mTextView;
GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 步驟1:創建手勢檢測器實例 & 傳入OnGestureListener接口(需要複寫對應方法)
mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture1", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
});
// 步驟2:創建 & 設置OnDoubleTapListener接口實現類
mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
// 1. 單擊事件
// 關於OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的區別
// onSingleTapConfirmed:再次點擊(即雙擊),則不會執行
// onSingleTapUp:手擡起就會執行
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("MyGesture", "onSingleTapConfirmed");
return false;
}
// 2. 雙擊事件
public boolean onDoubleTap(MotionEvent e) {
Log.i("MyGesture", "onDoubleTap");
return false;
}
// 3. 雙擊間隔中發生的動作
// 指觸發onDoubleTap後,在雙擊之間發生的其它動作,包含down、up和move事件;
public boolean onDoubleTapEvent(MotionEvent e) {
Log.i("MyGesture", "onDoubleTapEvent");
return false;
}
});
// 步驟3:重寫View的onTouch函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
mTextView = (TextView) findViewById(R.id.textView);
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
}
});
}
}
4. 測試效果
日誌效果如下
使用類:SimpleOnGestureListener
1. 作用
集成了兩個接口的手勢檢測功能
2. 與上述兩個接口的區別
- OnGestureListener和OnDoubleTapListener接口裏的函數都是強制必須重寫的
- 而SimpleOnGestureListener類的函數則可根據需要選擇性複寫,因爲SimpleOnGestureListener類本身已經實現了這兩個接口的所有函數,只是裏面全是空的而已
3. 使用步驟
// 步驟1:創建手勢檢測器實例
// 構造函數有3個,此處用的是第三個
// 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
// 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
// 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
// OnGestureListener接口的函數
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture1", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
// OnDoubleTapListener的函數
// 1. 單擊事件
// 關於OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的區別
// onSingleTapConfirmed:再次點擊(即雙擊),則不會執行
// onSingleTapUp:手擡起就會執行
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("MyGesture", "onSingleTapConfirmed");
return false;
}
// 2. 雙擊事件
public boolean onDoubleTap(MotionEvent e) {
Log.i("MyGesture", "onDoubleTap");
return false;
}
// 3. 雙擊間隔中發生的動作
// 指觸發onDoubleTap後,在雙擊之間發生的其它動作,包含down、up和move事件;
public boolean onDoubleTapEvent(MotionEvent e) {
Log.i("MyGesture", "onDoubleTapEvent");
return false;
}
});
// 步驟2-1:讓某個View檢測手勢 - 重寫View的onTouch函數,將View的觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
View.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true; // 注:返回true才能完整接收觸摸事件
}
});
// 步驟2-2:讓某個Activity檢測手勢:重寫Activity的dispatchTouchEvent函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
mGestureDetector.onTouchEvent(ev); // 讓GestureDetector響應觸碰事件
super.dispatchTouchEvent(ev); // 讓Activity響應觸碰事件
return false;
}
4. 實例說明
現在對一個TextView進行手勢檢測
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="600dp"
android:text="carson_ho Test"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView mTextView;
GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 步驟1:創建手勢檢測器實例 & 傳入OnGestureListener接口(需要複寫對應方法)
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
// OnGestureListener接口的函數
// 1. 用戶輕觸觸摸屏
public boolean onDown(MotionEvent e) {
Log.i("MyGesture1", "onDown");
return false;
}
// 2. 用戶輕觸觸摸屏,尚未鬆開或拖動
// 與onDown()的區別:無鬆開 / 拖動
// 即:當用戶點擊的時,onDown()就會執行,在按下的瞬間沒有鬆開 / 拖動時onShowPress就會執行
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
}
// 3. 用戶長按觸摸屏
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
}
// 4. 用戶輕擊屏幕後擡起
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
return true;
}
// 5. 用戶按下觸摸屏 & 拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture", "onScroll:");
return true;
}
// 6. 用戶按下觸摸屏、快速移動後鬆開
// 參數:
// e1:第1個ACTION_DOWN MotionEvent
// e2:最後一個ACTION_MOVE MotionEvent
// velocityX:X軸上的移動速度,像素/秒
// velocityY:Y軸上的移動速度,像素/秒
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
return true;
}
// OnDoubleTapListener的函數
// 1. 單擊事件
// 關於OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的區別
// onSingleTapConfirmed:再次點擊(即雙擊),則不會執行
// onSingleTapUp:手擡起就會執行
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("MyGesture", "onSingleTapConfirmed");
return false;
}
// 2. 雙擊事件
public boolean onDoubleTap(MotionEvent e) {
Log.i("MyGesture", "onDoubleTap");
return false;
}
// 3. 雙擊間隔中發生的動作
// 指觸發onDoubleTap後,在雙擊之間發生的其它動作,包含down、up和move事件;
public boolean onDoubleTapEvent(MotionEvent e) {
Log.i("MyGesture", "onDoubleTapEvent");
return false;
}
});
// 步驟2:重寫View的onTouch函數,將觸屏事件交給GestureDetector處理,從而對用戶手勢作出響應
mTextView = (TextView) findViewById(R.id.textView);
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
}
});
}
}
5. 測試效果
日誌效果如下
至此,關於Android手勢識別類GestureDetector類使用講解完畢。
總結
- 本文主要對
Android
手勢識別類:GestureDetector
類的使用進行全面講解 - 接下來我將繼續介紹
Android
開發中的相關知識,感興趣的同學可以繼續關注本人博客Carson_Ho的開發筆記