1. 程式人生 > >android 控制元件的滑動事件與點選事件衝突(GestureDetector,SimpleOnGestureListener)

android 控制元件的滑動事件與點選事件衝突(GestureDetector,SimpleOnGestureListener)

首先拿我的一個需求來舉例子:我有一個寫了一個小說閱讀器,在小說閱讀介面我想實現 可以點選翻頁,也可滑動翻頁這個就需要我們來處理點選與滑動的衝突了。
我們使用GestureDetector這個類來解決
首先建立一個GestureDetector物件,他有五個構造方法,我們使用沒有過時的
這裡寫圖片描述

需要實現OnGestureListener介面,這個介面有6個方法,6個方法的主要作用看程式碼片中的註釋

GestureDetector mGestureDetector= new GestureDetector(getApplicationContext(), 
new GestureDetector.OnGestureListener() {
            @Override
public boolean onDown(MotionEvent e) { // 按下時立刻觸發 //在這裡 如果想要監聽到滑動的話需要返回true return true; } @Override public void onShowPress(MotionEvent e) { // 短按,按下片刻後擡起,會觸發這個手勢,如果迅速擡起則不會 } @Override
public boolean onSingleTapUp(MotionEvent e) { // 釋放,手指離開觸時觸發(長按、滾動、滑動時,不會觸發這個手勢) //下面這段程式碼是我解決上面需求所用程式碼 只是想解決衝突可以無視 //這個方法是我們判斷點選事件的方法 float x=e.getX(); //獲取手指離開的x //width是螢幕的1/3寬 用來判斷點選的位置是在 左中右 哪個區域
if(x>0&&x<=width){ DownLeft(); //左 點選區域在左執行的方法 }else if(x>width&&x<=width*2){ DownHit(); //中 點選區域在中執行的方法 }else{ DownRight(); //右 點選區域在右執行的方法 } return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){ // 滑動,按下後滑動執行的方法 return false; } @Override public void onLongPress(MotionEvent e) { // 長按,觸控式螢幕按下後既不擡起也不移動,過一段時間後觸發 } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // 手指在觸控式螢幕上迅速移動,並鬆開的動作 //下面的程式碼是滑動的程式碼 只是想解決衝突可以無視 if(e1.getX()>e2.getX()){ //判斷滑動時按下的時的位置和擡起的位置 DownRight(); //按下》擡起 左滑 }else{ DownLeft(); //按下《擡起 右滑 } } return false; } }); // 監聽上面的手勢 實現 控制元件的 setOnTouchListener 方法 如: textview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //在這裡呼叫mGestureDetector的onTouchEvent就能監聽到控制元件的手勢 return mGestureDetector.onTouchEvent(event); } });

如果能你覺得上面的手勢少了,或者不滿足你的需求,那麼你可以寫一個類,繼承GestureDetector.SimpleOnGestureListener這個類實現了全部的手勢
這裡寫圖片描述

//這樣子使用 然後你可以在BookTextViewSleek這類中實現你想要的手勢操作
GestureDetector mGestureDetector= new GestureDetector(getApplicationContext(),new BookTextViewSleek());

下面我來介紹一下GestureDetector.SimpleOnGestureListener這個類的所能夠實現的手勢,這個類包括了上面GestureDetector.OnGestureListener()所有的手勢,但是我們也還是在來講一次

onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) :// 滑動,按下後滑動執行的方法
*
onSingleTapUp(MotionEvent e) :釋放,手指離開觸時觸發(長按、滾動、滑動時,不會觸發這個手勢)
*
onDown(MotionEvent e) : 按下時立刻觸發
*
onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :手指在觸控式螢幕上迅速移動,並鬆開的動作
*
onLongPress(MotionEvent e) :長按,觸控式螢幕按下後既不擡起也不移動,過一段時間後觸發
*
onShowPress(MotionEvent e) : 短按,按下片刻後擡起,會觸發這個手勢,如果迅速擡起則不會
*
onDoubleTap(MotionEvent e) :在雙擊的第二下,Touch down時觸發
*
onDoubleTapEvent(MotionEvent e) :通知DoubleTap手勢中的事件,包含down、up和move事件(這裡指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裡面還會發生down和up事件,這兩個事件由該函式通知);雙擊的第二下Touch down和up都會觸發,可用e.getAction()區分。
*
onSingleTapConfirmed(MotionEvent e) :用來判定該次點選是SingleTap而不是DoubleTap,如果連續點選兩次就是DoubleTap手勢,如果只點擊一次,系統等待一段時間後沒有收到第二次點選則判定該次點選為SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。這個方法不同於onSingleTapUp,他是在GestureDetector確信使用者在第一次觸控式螢幕幕後,沒有緊跟著第二次觸控式螢幕幕,也就是不是“雙擊”的時候觸發
*
onContextClick(MotionEvent e) :用的不多我也不會,查了一下好像是主要是用於檢測外部裝置按鈕的,不懂,不說了

1.當我們手指在view上按下馬上擡起的時候 執行的方法是onDown()—–>onSingleTapUp()

2.當我們手指按下並停留一下在view上再擡起的時候執行的方法是onDown()—onShowPress()—–onSingleTapUp()

3.當我們手指在view上滑動一下而不是瞬間擡起的時候,執行的方法是onDown()—onShowPress()—–onScroll()

4.當我們手指在view上快速滑動然後擡起,執行的方法是onDown()—onShowPress()—–onScroll()–onFling()

5.當我們手指按住view並且不滑動停留在view上一段時間,執行的方法是onDown()—onShowPress()—-onLongPress()

如果只是單純的滑動那麼其實實現setOnTouchListener事件監聽就行,判斷按下擡起的x 位置,但是怎麼說呢,可以實現但是使用起來不流暢