淺談Android 事件分發機制(二)
在上一篇文章中,淺談Android 事件分發機制(一)
,簡要分析了一下事件分發機制的原理,總結一下就是事件層層傳遞,直到被消費,原理看似簡單,但是在實際使用過程中,場景各不相同,複雜程度也就因產品而異,這篇文章就通過給view加移動來模擬事件分發。
觸控事件
事件 | 簡介 |
---|---|
ACTION_DOWN | 手指 初次接觸到螢幕 時觸發 |
ACTION_MOVE | 手指 在螢幕上滑動 時觸發,會多次觸發 |
ACTION_UP | 手指 離開螢幕 時觸發。 |
ACTION_CANCEL | 事件 被上層攔截 時觸發。 |
這裡涉及到幾個與手指觸控相關的常見事件:
事件 | 簡介 |
---|---|
ACTION_DOWN | 手指 初次接觸到螢幕 時觸發 |
ACTION_MOVE | 手指 在螢幕上滑動 時觸發,會多次觸發 |
ACTION_UP | 手指 離開螢幕 時觸發。 |
ACTION_CANCEL | 事件 被上層攔截 時觸發。 |
對於單指觸控移動來說,一次簡單的互動流程是這樣的:
手指落下(ACTION_DOWN) -> 移動(ACTION_MOVE) -> 離開(ACTION_UP)
座標系
Android座標系以手機螢幕左上角的頂點為座標原點,從該點向右為x軸正方向,從該點向下為y軸正方向。 上圖所示,一次觸控涉及到多種距離的計算,
上圖所標註的方法可以分為兩類,一類是View提供的方法,一類是MotionEvent提供的方法。
View提供的:getTop()
:獲取到view自身的頂邊到其父佈局頂邊的距離getLeft()
:獲取到view自身的左邊到其父佈局左邊的距離getRight()
:獲取到view自身的右邊到其父佈局左邊的距離getBottom()
:獲取到view自身底邊到其父佈局頂邊的距離
MotionEvent提供的方法:getX()
:獲取觸控點距離控制元件左邊的距離,即檢視座標getY()
: 獲取觸控點距離控制元件頂邊的距離,即檢視座標getRawX()
:獲取觸控點距離整個螢幕左邊的距離,即絕對座標getRawY()
:獲取觸控點距離整個螢幕頂邊的距離,即絕對座標
知道了以上的知識點後,基於文章一做view的移動,這裡還是三個檢視ViewC、ViewGroupB、ViewGroupA
C新增移動
給ViewC(藍色區域)新增移動
onTouchEvent
返回true,自身消費事件。手指按下
MotionEvent.ACTION_DOWN
,記錄當前距離控制元件左邊和頂邊的距離lastX
、lastY
。手指移動時
MotionEvent.ACTION_MOVE
,獲取當前距離控制元件左邊和頂邊的距離x
、y
,減去手指按下時記錄的距離lastX
、lastY
,計算得到移動的距離,移動的距離加上view距離父佈局的距離,得到相對於父佈局的四個點座標,layout
重新確認位置。手指離開
MotionEvent.ACTION_UP
,設定view距離父佈局的margin
,這邊的操作主要是固定view的位置,後續和檢視B一起移動時可固定位置。
private int lastX;
private int lastY;
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
//計算移動的距離
int offsetX = x - lastX;
int offsetY = y - lastY;
int l = getLeft() + offsetX;
int b = getBottom() + offsetY;
int r = getRight() + offsetX;
int t = getTop() + offsetY;
//重新確認位置
layout(l, t, r, b);
break;
case MotionEvent.ACTION_UP:
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
params.setMargins(getLeft(), getTop(), 0, 0);
break;
default:
break;
}
return true;
}
B新增移動
同樣給ViewGroupB
新增以上的程式碼用於B的移動。(藍色的檢視C,黃色的檢視B)
情況一:如上圖 這裡檢視B、C的
onTouchEvent
都返回true,在C區域滑動,viewC
消費了事件,不再傳遞給B;只有在B、C不重疊的區域滑動,C才會移動,這時沒有接觸到C,所以不會觸發C的事件。因為我們在C的MotionEvent.ACTION_UP
手指離開時固定了C到父佈局(B)的距離,所以C相對B的位置沒變。情況二:如上圖,將C的
onTouchEvent
返回false,在C區域滑動,事件沒有消費,傳遞給到了B,B可以滑動,在不重疊區域一樣可以滑動B。如果B把事件攔截了
onInterceptTouchEvent
返回true,那麼效果和情況二相同的,不管C的onTouchEvent
返回啥,都響應不了。這裡模擬了檢視B、C的滑動,A的話原理相同,這裡就不再描述。
淺談android事件分發的兩篇文章結束了,這裡只是簡單描述模擬了事件分發。日常專案中若是遇到情況怕是更為複雜,想要徹底玩轉事件分發機制還需要進一步的研究。
歡迎關注我的部落格:http://blog.manjiexiang.cn/
歡迎關注微訊號:春風十里不如認識你
相關文章
- 淺談Android中的事件分發機制Android事件
- Android事件分發機制Android事件
- 淺談JS事件機制與React事件機制JS事件React
- Android事件分發機制探究Android事件
- Android事件分發機制解析Android事件
- Android事件分發機制三:事件分發工作流程Android事件
- android事件分發機制詳解Android事件
- Android的MotionEvent事件分發機制Android事件
- Android 事件分發機制的理解Android事件
- 完全理解android事件分發機制Android事件
- 圖解 Android 事件分發機制圖解Android事件
- Android ViewGroup事件分發機制AndroidView事件
- 事件分發機制(二):原始碼篇事件原始碼
- iOS事件分發機制(二)The Responder ChainiOS事件AI
- Android View 的事件體系 -- 事件分發機制AndroidView事件
- Android事件分發機制簡單理解Android事件
- Android 事件分發機制原始碼解析Android事件原始碼
- Android事件分發:從原始碼角度分析View事件分發機制Android事件原始碼View
- 10分鐘理解 Android View 事件分發機制AndroidView事件
- 淺談任務分發中的機制與併發
- View事件分發機制View事件
- 面試:講講 Android 的事件分發機制面試Android事件
- 【Android原始碼】View的事件分發機制Android原始碼View事件
- Android ViewGroup 事件分發機制詳解AndroidView事件
- android事件分發(二)Android事件
- 深入淺出Android事件分發機制:最全面最易懂:基礎篇(一)Android事件
- 《Android開發藝術探索》——View事件分發機制AndroidView事件
- Android事件分發機制,你瞭解過嗎?Android事件
- Android 事件分發機制原始碼解析-view層Android事件原始碼View
- 【Android基礎】講講Android的事件分發機制Android事件
- View事件分發機制分析View事件
- 淺談前端和移動端的事件機制前端事件
- Android事件分發機制五:面試官你坐啊Android事件面試
- Android自定義View之事件分發機制總結AndroidView事件
- 基於原始碼分析 Android View 事件分發機制原始碼AndroidView事件
- Android 事件分發機制原始碼詳解-最新 APIAndroid事件原始碼API
- Android從原始碼角度剖析View事件分發機制Android原始碼View事件
- Android事件分發機制之原始碼完美解析(上)Android事件原始碼