MotionEvent
用戶觸摸手機屏幕后會產(chǎn)生一系列的事件,幾個典型的事件如下:
- ACTION_DOWN : 手指剛接觸屏幕的一瞬間.
- ACTION_MOVE : 手指按下后在屏幕上移動.
- ACTION_UP : 手指從屏幕上離開的一瞬間.
事件一般不會單獨存在, 都是以一個事件序列的形式存在的.比如,手機按下后就會有離開的時候.常見的事件序列如下:
- 點擊屏幕后松開(不滑動) :
DOWN --> UP
. - 點擊屏幕,在屏幕上滑動,松開:
DWON --> MOVE...MOVE --> UP
既然是在屏幕上操作,那么一定會有相關的位置信息.Android系統(tǒng)為我們提供了兩組方法獲取位置信息:
-
getX()/getY()
: 獲取以當前View左上角為坐標原點的X,Y坐標值. -
getRawX()/getRawY()
: 以手機屏幕左上角,為坐標原點的,x和y值.
坐標展示
TouchSlop
TouchSlop 是系統(tǒng)認為進行了滑動操作的最小距離, 也就是說如果滑動距離小于這個距離, 則則系統(tǒng)認為沒有進行滑動操作.它定義在frameworks/base/core/res/values/config.xml
中.
<!-- Base "touch slop" value used by ViewConfiguration as a
movement threshold where scrolling should begin. -->
<dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
從源碼中我們可以到他的單位是 dp 也就是說不同像素密度的設備上他的值是不一樣的.
同時我們也可以通過代碼獲取到他的值
ViewConfiguration.get(context).getScaledTouchSlop()
在實際開發(fā)中我們可以獲取該常量來進行一些過濾操作, 以此達到更好的用戶體驗效果.
VelocityTracker
速度追蹤(VelocityTracker) 用于計算在手指滑動過程中速度. 包括水平方向,豎直方向的速度.使用步驟如下 :
- 添加要追蹤的點擊事件. 在
onTouchEvent
方法中.
// 獲取速度追蹤對象
VelocityTracker vt = VelocityTracker.obtain();
// 添加事件.
vt.addMovement(event);
- 獲取當前移動速度
// 計算速度. 每次獲取速度前都需要調用這個方法.
// 方法參數(shù)是時間單位,ms 1000ms 內(nèi)經(jīng)過的像素數(shù)據(jù).
vt.computeCurrentVelocity(1000);
// 獲取速度
int vX = (int) vt.getXVelocity();
int vY = (int) vt.getYVelocity();
有幾點需要注意:
- 每次 獲取速度前都需要進行速度計算,通過調用computeCurrentVelocity方法進行速度計算.
- 測量的速度是指在指定的時間內(nèi)劃過的像素數(shù), 比如時間間隔設置為1000, 假如在1000ms向右內(nèi)劃過了 100像素,那么速度就是100. 可以看出其本質就是測量在給定的時間內(nèi)移動的像素數(shù).
- 同時速度可能是負值, 比如向左移動/向上移動都是負值.聯(lián)系Android坐標系,這點非常好理解了.
- 速度公式 :
速度 = (終點位置 - 起點位置) / 時間段
-
computeCurrentVelocity
的參數(shù)就相當于是指定了時間單位. 比如:設置為 100, 那么速度就成了 10 .他是在100ms經(jīng)過的像素數(shù)就是速度, 10像素/100ms. 這個有點別扭,但是只要是記住指定的是時間單位就行了.
- 當不使用時釋放資源
vt.clear();
vt.recycle();
**完整使用代碼 : **
@Override
public boolean onTouchEvent(MotionEvent event) {
// 第一步 : 將事件添加到速度跟蹤中.
VelocityTracker vt = VelocityTracker.obtain();
vt.addMovement(event);
// 第二步 : 獲取當前速度.
// 計算速度. 每次獲取速度前都需要調用這個方法.
// 方法參數(shù)是時間單位,ms 1000ms 內(nèi)經(jīng)過的像素數(shù)據(jù).
vt.computeCurrentVelocity(1000);
// 獲取速度
int vX = (int) vt.getXVelocity();
int vY = (int) vt.getYVelocity();
Log.d(TAG, "onTouchEvent vX : " + vX);
Log.d(TAG, "onTouchEvent vY : " + vY);
// 第三步 : 不使用時釋放資源.
vt.clear();
vt.recycle();
return super.onTouchEvent(event);
}