详解
为什么要了解onTouchEvent
在使用onTouchEvent时,可能会涉及到手指在屏幕上滑动或者按下等活动,那手机怎么判断这个触碰的点在哪个位置,其中有一个对触碰点的坐标(x,y)的使用。
在平时的手机软件上,到处都是控件构成的界面,那么如果我们把手指落在这个控件上时需要执行某些操作,问题来了,怎么判断现在的触碰点的坐标是落在了这个控件的内部的,此时就有一个控件的相对坐标,但这个控件的坐标和触碰点的坐标的参考点是不一样的
不同的参考点
屏幕的构成
我们先来了解一下屏幕的构成:
从上到下分别为
statusBar(任务栏)
actionBar(活动栏)
content(内容区域)
navigationBar(导航栏)
不同的参考点
- 控件的参考点是相对于内容区域的
- 触碰点的参考点是相对于整个屏幕的
直接上图
看图我们可以发现
触碰.y 和 控件.top 相差 任务栏、活动栏、导航栏 的高度
所以在计算是我们需要获得 任务栏+活动栏+导航栏 的高度
但有些手机是没有导航栏的,有时使用时可以不同获得导航栏的高度
下面我们就来看看怎么获取这个高度
获取任务栏+活动栏+导航栏的高度
任务栏高度+活动栏高度+导航栏高度 = 整个屏幕的高度 - 内容区域高度 - 导航栏高度
获取整个屏幕的高度
需要判断minSdkVersion的版本,低于30和高于等于30获取屏幕的方法是不一样的
var screenHeight = 0
//判断minSdkVersion的版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
screenHeight = windowManager.currentWindowMetrics.bounds.height()
}else{
val mMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(mMetrics)
screenHeight = mMetrics.heightPixels
}
获取内容区域的高度
val rect = Rect()
val content = window.findViewById<ViewGroup(Window.ID_ANDROID_CONTENT)
content.getDrawingRect(rect)
val contenHeight = rect.height()
获取导航栏的高度
val resourceId = resources.getIdentifier("navigation_bar_height","dimen","android")
val navBarHeight = resources.getDimensionPixelSize(resourceId)
任务栏高度+活动栏高度+导航栏高度 = 整个屏幕的高度 - 内容区域高度 - 导航栏高度
val barHeight = screenHeight - contentHeight - navBarHeight
判断触碰点是否落在控件的内部
先将两个的参考点转化为相同的,然后用Rect()中的contains()方法比较两个点。
下面就讲述怎么判断现在的触碰点的坐标是落在了这个控件的内部的
方法一:控件的参考点改为和触碰点一样
也就是说将控件的转化成Rect
//这里的dot:imageView就是控件
val dot:ImageView
Rect(
dot.x.toInt(),
dot.y.toInt(),
(dot.x + dot.width).toInt(),
(dot.y + dot.height).toInt())
方法二:触碰点的参考点改为父容器
也就是说将触碰点的参考点改成内容区域
val event:MotionEvent
//binding.dotContainer是父容器
val y = event.y - barHeight - binding.dotContainer.y
val touchPoint = Point()
touchPoint.x = event.x.toInt()
touchPoint.y = y.toInt()