2020.8.8
Activity的功能:
1.管理界面的生命周期
2.接收事件(触摸事件)
一.触摸事件传递解析
touch事件的传递.png
当手指按下时会首先调用onUserInteraction()方法,这是触摸事件的开始
- 事件类型:MotionEvent类来管理
ACTION_DOWN 按下
ACTION_MOVE 移动
ACTION_UP 离开屏幕
ACTION_CANCEL 被其他应用打断
触摸事件源码分析.png
进过上面的触摸事件分发过程,如果子控件需要接收触摸事件,就必须实现onTouchEvent
该方法的返回值会Boolean,当返回值为true时,表示这个事件已经被消费,就不会继续传递
当返回值为false是,表示这个事件没有被消费,就继续传递
二.触摸事件的应用
当我们的手指按下或者在屏幕上滑动时,系统就会获取到手指点在屏幕上的位置(x,y),如果这个点落在了某个控件内部,我们希望对这个控件做出一些改变,以完成某个效果,由于控件和触摸点的相对坐标的参考是不同的,所以下面将介绍两种方法来判断触摸点是否在某个控件内部
坐标图解.png
- event可以获取触摸点的(x,y),但该坐标是相对于整个屏幕的
而view.x和view.y获取的坐标是相对于容器的,因此需要进行转换靠齐 - Point(x,y)类专门用来管理点的坐标
Rect(left,top,right,bottom)类专门用来管理矩形区域 - 通过Rect(view.x,view.y,view.x+view.width,view.y+view.height)便可创建一个相对于容器的矩形区域
- Rect()内部有一个方法contains(int x, int y)便可判断触摸点是否在矩形区域即控件内部
- 将控件转换为相对于整个屏幕的坐标区域,而非容器
以下代码便可获取控件相对于屏幕的矩形区域
val rect=Rect()
view.requestRectangleOnScreen(rect)
rect.right=rect.left+view.width
rect.bottom=rect.top+view.height
注意的是requestRectangleOnScreen()只是获取了相对于屏幕的x,y坐标,而并没有获取到right和bottom,这点很关键,需要自己在进行添加
-
将触摸点转换为相对于容器的坐标,此方法只需要用event获取的点的y坐标减去bar和状态栏的高度即可,而bar和状态栏的高度可以用屏幕的高度减去容器的高度
高度计算.png
//获取屏幕尺寸
val display=DisplayMetrics()
//获取显示的一个矩阵
windowManager.defaultDisplay.getMetrics(display)
//获取内容绘制区域的尺寸
val drawRect=Rect()
//通过获取window上content容器->容器的rect
window.findViewById<ViewGroup>(Window.ID_ANDROID_CONTENT).getDrawingRect(drawRect)
//bar和状态的高度即顶部高度
val topHeight=display.heightPixels-drawRect.height()
//将event的坐标进行转换,相对于容器
val point=Point(event.x.toInt(),(event.y-topHeight).toInt())
以上便是两种进行判断点是否在控件内的方法,但第二种方式的计算顶部高度最好使用懒加载的方式,使用的时候才计算,而且只计算一次,这点很重要