★60.自定義控件 ★19.MotionEvent詳解dd

單點觸控

事件表

事件 簡介
ACTION_DOWN 手指 初次接觸到屏幕 時觸發(fā)。
ACTION_MOVE 手指 在屏幕上滑動 時觸發(fā),會多次觸發(fā)。
ACTION_UP 手指 離開屏幕 時觸發(fā)。
ACTION_CANCEL 事件 被上層攔截 時觸發(fā)。
ACTION_OUTSIDE 手指 不在控件區(qū)域 時觸發(fā)

方法表

方法 簡介
getAction() 獲取 事件類型
getX() 獲得 觸摸點 在當(dāng)前ViewX坐標 。
getY() 獲得 觸摸點 在當(dāng)前ViewY坐標 。
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ù)的flagsFLAG_WATCH_OUTSIDE_TOUCH。
  • 除了Dialog之外,最可能看到ACTION_OUTSIDE的場景是 懸浮窗

多點觸控

簡介

  • 發(fā)生 多點觸控 時,最先接收到的 觸摸點 作為 主觸摸點 ,之后接收到的 觸摸點 作為 輔助觸摸點 。

觸摸點索引 與 觸摸點ID

  • 單次觸摸事件ACTION_DOWNACTION_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移動事件歷史觸摸壓力

滑動沖突處理

  1. RecyclerView收到了一個ACTION_DOWN事件,先假定是個點擊事件,傳遞給對應(yīng)ItemView,詢問ItemView是否需要這個事件。
  2. 接著,RecyclerView收到一個ACTION_MOVE事件,且移動的方向和RecyclerView的可滑動方向一致,此時可以判斷這個事件是 滾動事件 ,因此進行 攔截 。
  3. 因為上層View進行了 攔截 ,所以對應(yīng)的ItemView會收到一個 ACTION_CANCEL ,并且不會再收到后續(xù)事件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容