最近專案中需要實現手勢上滑或點擊滑出介面的效果,實現上是利用GestureDetector,然後在onFling中判斷,但遇到一個問題:手勢上滑是針對整個佈局的,但如果有對單獨的View設定點選監聽,在該View上的手勢上滑會失效。
如果這個View本身就是專門用於點擊的,那並沒有什麼問題,可惜的是,這個View的尺寸不大,所以要求擴大點擊區域。
我們首先能想到的方法就是用一個容器將該View包起來,類似RelativeLayout,LinearLayout等,但這樣佈局的層級就會再加多一層。
我們能否想到不用增加層級也能實現點擊區域擴大的方法呢?
GestureDetector是Android提供的手勢操作類,它提供了單擊,雙擊,長按等操作,並且會將這些事件傳給onTouch,因此我們可以利用這個來判斷觸發單擊事件的到底是哪個控件。
但是我們的問題是擴大點擊區域,而不是識別控件,因此需要知道使用者的點擊動作到底是落在哪個區域。
所幸,MotionEvent提供了事件發生時候的座標,這樣我們就能知道點擊時候的座標,進一步確定是否在指定的區域範圍內。
MotionEvent是Android中觸控方面編碼的一個至關重要的類,它提供了用戶在螢幕上的觸控資訊。我們可以透過MotionEvent取得到觸控的事件類型,觸控的座標,現在已經支援多點觸碰,還能進一步取得觸控的索引資訊。
我們先上程式碼:
@Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ int downX = (int)event.getX(); int[] location = new int[2]; ivMore.getLocationInWindow(location); if(Math.abs(downX - location[0]) <= 50){ ... } } return gestureDetector.onTouchEvent(event); }
我們先透過MotionEvent的getAction,取得觸控的事件類型,點選的類型為ACTION_DOWN,然後透過MotionEvent的getX取得點擊的x座標,然後再透過getLocationInWindow取得指定的View的座標,這裡指定該元件的x軸座標正負50(表示左右範圍)內為觸發範圍。
我們現在可以不增加佈局層級也能擴大點擊範圍了。
利用GestureDetector實現上滑判斷是很簡單的,只要實現OnGestureListener接口,在對應的回調中進行我們指定的操作,不過因為GestureDetector本身並不捕獲觸控事件,所以要再實現onTouch事件,並調用GestureDetector的onTouchEvent,將對應的事件傳過去。
滑動的操作是在onFling回調中進行的,該回調會傳進兩個歷史記錄的MotionEvent,我們只要判斷它們的Y軸坐標是否有變化即可。
Android的觸控是一個相當大的話題範圍,我們只要在明確自己需求的前提上,去尋找對應的快速解決方案。