2020.8.8
Activity的功能:
1.管理界面的生命周期
2.接收事件(觸摸事件)
一.觸摸事件傳遞解析
當手指按下時會首先調(diào)用onUserInteraction()方法端衰,這是觸摸事件的開始
- 事件類型:MotionEvent類來管理
ACTION_DOWN?按下
ACTION_MOVE?移動
ACTION_UP?離開屏幕
ACTION_CANCEL?被其他應(yīng)用打斷
進過上面的觸摸事件分發(fā)過程旅东,如果子控件需要接收觸摸事件十艾,就必須實現(xiàn)onTouchEvent
該方法的返回值會Boolean,當返回值為true時忘嫉,表示這個事件已經(jīng)被消費案腺,就不會繼續(xù)傳遞
當返回值為false是康吵,表示這個事件沒有被消費,就繼續(xù)傳遞
二.觸摸事件的應(yīng)用
當我們的手指按下或者在屏幕上滑動時同辣,系統(tǒng)就會獲取到手指點在屏幕上的位置(x,y)耍铜,如果這個點落在了某個控件內(nèi)部,我們希望對這個控件做出一些改變棕兼,以完成某個效果,由于控件和觸摸點的相對坐標的參考是不同的靶衍,所以下面將介紹兩種方法來判斷觸摸點是否在某個控件內(nèi)部
- event可以獲取觸摸點的(x,y)茎芋,但該坐標是相對于整個屏幕的
而view.x和view.y獲取的坐標是相對于容器的,因此需要進行轉(zhuǎn)換靠齊 - Point(x,y)類專門用來管理點的坐標
Rect(left,top,right,bottom)類專門用來管理矩形區(qū)域 - 通過Rect(view.x涛酗,view.y偷厦,view.x+view.width,view.y+view.height)便可創(chuàng)建一個相對于容器的矩形區(qū)域
- Rect()內(nèi)部有一個方法contains(int x, int y)便可判斷觸摸點是否在矩形區(qū)域即控件內(nèi)部
- 將控件轉(zhuǎn)換為相對于整個屏幕的坐標區(qū)域剖笙,而非容器
以下代碼便可獲取控件相對于屏幕的矩形區(qū)域
val rect=Rect()
view.requestRectangleOnScreen(rect)
rect.right=rect.left+view.width
rect.bottom=rect.top+view.height
注意的是requestRectangleOnScreen()只是獲取了相對于屏幕的x,y坐標请唱,而并沒有獲取到right和bottom,這點很關(guān)鍵十绑,需要自己在進行添加
-
將觸摸點轉(zhuǎn)換為相對于容器的坐標,此方法只需要用event獲取的點的y坐標減去bar和狀態(tài)欄的高度即可扳躬,而bar和狀態(tài)欄的高度可以用屏幕的高度減去容器的高度
//獲取屏幕尺寸
val display=DisplayMetrics()
//獲取顯示的一個矩陣
windowManager.defaultDisplay.getMetrics(display)
//獲取內(nèi)容繪制區(qū)域的尺寸
val drawRect=Rect()
//通過獲取window上content容器->容器的rect
window.findViewById<ViewGroup>(Window.ID_ANDROID_CONTENT).getDrawingRect(drawRect)
//bar和狀態(tài)的高度即頂部高度
val topHeight=display.heightPixels-drawRect.height()
//將event的坐標進行轉(zhuǎn)換坦报,相對于容器
val point=Point(event.x.toInt(),(event.y-topHeight).toInt())
以上便是兩種進行判斷點是否在控件內(nèi)的方法,但第二種方式的計算頂部高度最好使用懶加載的方式片择,使用的時候才計算,而且只計算一次啰挪,這點很重要