單點觸控
事件表
| 事件 | 簡介 |
|---|---|
ACTION_DOWN |
手指 初次接觸到屏幕 時觸發(fā)。 |
ACTION_MOVE |
手指 在屏幕上滑動 時觸發(fā),會多次觸發(fā)。 |
ACTION_UP |
手指 離開屏幕 時觸發(fā)。 |
ACTION_CANCEL |
事件 被上層攔截 時觸發(fā)。 |
ACTION_OUTSIDE |
手指 不在控件區(qū)域 時觸發(fā) |
方法表
| 方法 | 簡介 |
|---|---|
getAction() |
獲取 事件類型 。 |
getX() |
獲得 觸摸點 在當(dāng)前View的 X坐標 。 |
getY() |
獲得 觸摸點 在當(dāng)前View的 Y坐標 。 |
getRawX() |
獲得 觸摸點 在整個屏幕的 X坐標 。 |
getRawY() |
獲得 觸摸點 在整個屏幕的 Y坐標 。 |
簡單示例
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
// 手指按下
break;
case MotionEvent.ACTION_MOVE:
// 手指移動
break;
case MotionEvent.ACTION_UP:
// 手指抬起
break;
case MotionEvent.ACTION_CANCEL:
// 事件被攔截
break;
case MotionEvent.ACTION_OUTSIDE:
// 超出區(qū)域
break;
}
return super.onTouchEvent(event);
}
ACTION_CANCEL
-
觸摸事件流程 :
ACTION_DOWN -> ACTION_MOVE -> ACTION_UP。 -
觸摸事件流程中間 :已經(jīng)接收到
ACTION_DOWN事件,但是還沒有接收到ACTION_UP事件。 - 子
View在 觸摸事件流程中間 時,父View攔截了觸摸事件,此時子View會接收到ACTION_CANCEL事件。
ACTION_OUTSIDE
-
ACTION_OUTSIDE不是在View內(nèi)部滑動到外部的時候產(chǎn)生的。 -
ACTION_OUTSIDE用于Dialog這樣的特殊窗口,使其能夠接收到視圖區(qū)域外的事件。 - 默認情況下,無法接收到
ACTION_OUTSIDE,需要設(shè)置視圖的WindowManager布局參數(shù)的flags為FLAG_WATCH_OUTSIDE_TOUCH。 - 除了
Dialog之外,最可能看到ACTION_OUTSIDE的場景是 懸浮窗 。
多點觸控
簡介
- 發(fā)生 多點觸控 時,最先接收到的 觸摸點 作為 主觸摸點 ,之后接收到的 觸摸點 作為 輔助觸摸點 。
觸摸點索引 與 觸摸點ID
-
單次觸摸事件 :
ACTION_DOWN、ACTION_UP、ACTION_MOVE。 -
觸摸事件流程 :
ACTION_DOWN -> ACTION_MOVE -> ACTION_UP。 -
觸摸點索引 與 觸摸點ID 都是用于標識 觸摸點 ,但是:
- 觸摸點索引 只保證在 單次觸摸事件 有效。
- 觸摸點ID 能保證在整個 觸摸事件流程 有效。
- 通常使用 觸摸點ID 來標識 觸摸點 ,而不是 觸摸點索引 。
事件表
| 事件 | 簡介 |
|---|---|
ACTION_DOWN |
第一個 手指 初次接觸到屏幕 時觸發(fā)。 |
ACTION_MOVE |
手指 在屏幕上滑動 時觸發(fā),會多次觸發(fā)。 |
ACTION_UP |
最后一個 手指 離開屏幕 時觸發(fā)。 |
ACTION_POINTER_DOWN |
有其他手指按下( 即按下之前已經(jīng)有手指在屏幕上 )。 |
ACTION_POINTER_UP |
有其他手指抬起( 即抬起之后仍然有手指在屏幕上 )。 |
方法表
| 方法 | 簡介 |
|---|---|
getActionMasked() |
獲取 事件類型 。 |
getActionIndex() |
獲取 觸摸點索引 。 |
getPointerCount() |
獲取 觸摸點 個數(shù)。 |
getPointerId(int pointerIndex) |
使用 觸摸點索引 獲取 觸摸點ID 。 |
findPointerIndex(int pointerId) |
使用 觸摸點ID 獲取 觸摸點索引 。 |
getX(int pointerIndex) |
獲取 觸摸點索引 對應(yīng)的 X坐標 。 |
getY(int pointerIndex) |
獲取 觸摸點索引 對應(yīng)的 Y坐標 。 |
getAction() 與 getActionMasked()
-
多點觸控 使用
getActionMasked()來獲取 事件類型 。 -
單點觸控 使用
getAction()(或getActionMasked())來獲取 事件類型 。
移動事件歷史
簡介
-
移動事件歷史 :由于
ACTION_MOVE事件的產(chǎn)生十分頻繁,為了提高性能,會將多個ACTION_MOVE事件打包放進同一個MotionEvent中批量處理。 - 單點觸控 和 多點觸控 都可以用 移動事件歷史 。
方法表
| 事件 | 簡介 |
|---|---|
getHistorySize() |
獲取 移動事件歷史集合 大小。 |
getHistoricalX(int pos) |
獲取第pos個的 移動事件歷史 的 X坐標 。 |
getHistoricalY(int pos) |
獲取第pos個的 移動事件歷史 的 Y坐標 。 |
getHistoricalX(int pointerIndex, int pos) |
獲取 觸摸點索引 對應(yīng)的第pos個 移動事件歷史 的 X坐標 。 |
getHistoricalY(int pointerIndex, int pos) |
獲取 觸摸點索引 對應(yīng)的第pos個 移動事件歷史 的 Y坐標 。 |
觸摸事件時間
| 方法 | 簡介 |
|---|---|
getDownTime() |
獲取手指按下時的時間,單位為 毫秒 。 |
getEventTime() |
獲取當(dāng)前事件發(fā)生的時間,單位為 毫秒 。 |
getHistoricalEventTime(int pos) |
獲取第pos個 移動事件歷史 發(fā)生的時間,單位為 毫秒 。 |
觸摸面積 與 觸摸壓力
簡介
- 觸摸面積 識別和 觸摸壓力 識別是需要硬件支持的。
- 目前,大部分設(shè)備的屏幕不支持識別 觸摸壓力 ,但能夠大致識別 觸摸面積 。
- 大部分設(shè)備是使用 觸摸面積 來模擬 觸摸壓力 的。
方法表
| 方法 | 簡介 |
|---|---|
getSize() |
獲取 觸摸面積 。 |
getSize(int pointerIndex) |
獲取 觸摸點索引 對應(yīng)的 觸摸面積 。 |
getHistoricalSize(int pos) |
獲取第pos次 移動事件歷史 的 觸摸面積 。 |
getHistoricalSize(int pointerIndex, int pos) |
獲取 觸摸點索引 對應(yīng)的第pos次 移動事件歷史 的 觸摸面積 。 |
getPressure() |
獲取 觸摸壓力 。 |
getPressure(int pointerIndex) |
獲取 觸摸點索引 對應(yīng)的 觸摸壓力 。 |
getHistoricalPressure(int pos) |
獲取第pos次 移動事件歷史 的 觸摸壓力 。 |
getHistoricalPressure(int pointerIndex, int pos) |
獲取 觸摸點索引 對應(yīng)的第pos次 移動事件歷史 的 觸摸壓力 。 |
滑動沖突處理
-
RecyclerView收到了一個ACTION_DOWN事件,先假定是個點擊事件,傳遞給對應(yīng)ItemView,詢問ItemView是否需要這個事件。 - 接著,
RecyclerView收到一個ACTION_MOVE事件,且移動的方向和RecyclerView的可滑動方向一致,此時可以判斷這個事件是 滾動事件 ,因此進行 攔截 。 - 因為上層
View進行了 攔截 ,所以對應(yīng)的ItemView會收到一個ACTION_CANCEL,并且不會再收到后續(xù)事件。