Android: 觸屏fling/scroll/drag的區別及其詳細過程


Google了一下,終於搞清了touch screen下的幾種操作模式(對應的是事件)。

對於一個view, 常用的操作有點擊(click)和長按(long press)二種。實際上,這些操作類型是Android內部在onTouchEvent(MotionEvent event)里對用戶的動作做了一定的分析,從而通知應用程序是發生了點擊還是長按等事件。

有時,我們需要的並不僅限於這兩種操作。我們可以借助GestureDetector來分析出更細致的操作類型。基本的過程就是創建一個myGestureDetector對象,傳入自己定義的myOnGestureListener對象,在自己的onTouchEvent回調函數中將接收到的event傳給myGestureDetector進行分析,myOnGestureListener會回調我們定義的動作。
【 從 GestureDetector.SimpleOnGestureListener派生出myListener 會更簡單,因為這個類已經實現了全部接口,只是沒有什么實際有用的功能。】

參考以下代碼(for an Activity):

// -------------------------------------------------------------------------------

private GestureDetector mGestureDetector;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    mGestureDetector = new GestureDetector(this, new MyGestureListener());
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return mGestureDetector.onTouchEvent(event);
}


class MyGestureListener extends GestureDetector.OnGestureListener{ //共有6個方法:

    // 用戶輕觸觸屏:Touch down(僅一次)時觸發, e為down時的MotionEvent:
    boolean onDown(MotionEvent e){return true;}

    // 用戶輕觸觸屏,且尚未松開或拖動
    //   在Touch down(僅一次)之后一定時間(115ms)觸發,e為down時的MotionEvent:
    void onShowPress(MotionEvent e){return true;}

    // 用戶(輕觸觸屏后)松開:Touch up(僅一次)時觸發,e為up時的MotionEvent:
    boolean onSingleTapUp(MotionEvent e){return true;}

    // 用戶輕觸觸屏,並拖動:
    //   按下並滑動時觸發,e1為down(僅一次)時的MotionEvent,e2為move(多個)時的MotionEvent:
    boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){return true;}

    // 用戶長按觸屏(此View必須是可長按的: myView->setLongClickable(true);):
    //   在Touch down之后一定時間(500ms)后,由多個down事件觸發,e為down時的MotionEvent:
    void onLongPress(MotionEvent e){return true;}

    // 用戶按下觸屏、快速移動后松開:
    //   按下並快速滑動一小段距離(多個move),up時觸發,e1為down(僅一次)時的MotionEvent,
    //   e2為up(僅一次)時的MotionEvent:
    boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){return true;}
}
// -------------------------------------------------------------------------------

至於doubletap的檢測,可以通過設置mGestureDetector的OnDoubleTapListener來實現:

GestureDetector.OnDoubleTapListener doubleTapListener = new GestureDetector.OnDoubleTapListener() {

    // 完成一次單擊,並確定(300ms內)沒有發生第二次單擊事件后觸發,e為down時的MotionEvent:
    boolean onSingleTapConfirmed(MotionEvent e){return true;}
 
    // 第二次單擊down時觸發,e為第一次down時的MotionEvent:
    boolean onDoubleTap(MotionEvent e){return true;}

    // 第二次單擊down、move和up時都觸發,e為不同時機下的MotionEvent:
    boolean onDoubleTapEvent(MotionEvent e){return true;}
}
mGestureDetector.setDoubleTapListener(doubleTapListener);
// -------------------------------------------------------------------------------


具體地說,典型的觸屏事件及其listener執行的流程見下:

1). 單擊事件的執行流程:
  有兩種情況,一種是時間很短,一種時間稍長。
  時間很短:onDown ----> onSingleTapUp ----> onSingleTapConfirmed
  時間稍長:onDown ----> onShowPress   ----> onSingleTapUp ----> onSingleTapConfirmed

2). 長按事件
   onDown ----> onShowPress ----> onLongPress

3.拋(fling):手指觸動屏幕后,稍微滑動后立即松開:
   onDown ----> onScroll ----> onScroll ----> onScroll ----> ………  ----> onFling

4.拖動(drag)
   onDown ----> onScroll ----> onScroll ----> onFiling
   注意:有的時候會觸發onFiling,但是有的時候不會觸發,z這是因為人的動作不標准所致。

<完>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM