手机屏幕坐标系与数学坐标系的不同,主要留意y轴方向。
(1)屏幕坐标系/Android坐标系
以屏幕左上角为原点。如图所示,图中绿色边框位置为屏幕所在区域,其中绿色边框左上角为原点。
(2)View坐标系
如图,手机屏幕区域,即上图绿色边框围裹部分,可分为状态栏(即wifi信号、电量显示区)、标题栏、View可绘制区域。其中,标题栏和可绘制区域为我们的APP应用区域。
View的坐标是相对父容器而言的,以相对父容器的左上角为原点。上图中可绘制区域(褐色边框部分)的左上角位置,就是整个坐标系统的原点。
关于上面ABCD点的坐标,先普及一下知识:
View的坐标方法 |
解释 |
getLeft() |
返回View自身左边到父布局左边的距离 |
getTop() |
返回View自身顶边到父布局顶边的距离 |
getRight() |
返回View自身右边到父布局左边的距离 |
getBottom() |
返回View自身底边到父布局顶边的距离 |
getX() |
返回值为getLeft()+getTranslationX(),当setTranslationX()时getLeft()不变,getX()变。 |
getY() |
返回值为getTop()+getTranslationY(),当setTranslationY()时getTop()不变,getY()变。 |
getLocationOnScreen() |
获取view在当前屏幕内的绝对坐标(Android坐标系,包含状态栏和标题栏) |
getLocationInWindow () |
获取view在其父布局中的相对坐标 |
这样,我们就可以算出它们的坐标(该控件的父布局是根布局,所以可以看做是在屏幕中的坐标)了。
A( view.getLeft() , view.getTop())、B( view.getRight() , view.getTop())、
C( view.getLeft() , view.getBottom())、D( view.getRight() , view.getBottom())
同样的,我们可以算出A1B1C1D1相对于父布局ViewGroup的坐标。
!注意:
① 前面四个方法获取的不是在屏幕中的坐标,是相对于父控件的相对坐标(原始的位置);
② getX()和getY(),主要用于获取控件移动后的相对位置(视觉上的位置),但是并非View的坐标直接加减移动距离。eg.
view.setTranslationX(100),view向右移动了100,但是这只是视觉上的移动,真实位置不变,所以获取视觉上的位置不能用原先的getLeft()+100,这是错误的,而是得用getX()。
③ getLocationOnScreen()与getLocationInWindow()获取的时机:
必须在窗体获得焦点之后才可以,否则返回为空。我们可以复写Activity的onWindowFocusChanged()方法,在该方法体内获取具体的坐标。网上还提供了另外一种方法,链接
MotionEvent相关方法 | 解释 |
---|---|
getX() | 当前触摸点距离当前View左边的距离 |
getY() | 当前触摸点距离当前View顶边的距离 |
getRawX() | 当前触摸点距离整个屏幕左边的距离(不管App是否有状态栏、全屏等) |
getRawY() | 当前触摸点距离整个屏幕顶边的距离(不管App是否有状态栏、全屏等) |
注意:这里的屏幕,指的是屏幕显示区,而不是整个手机界面,见上面的屏幕坐标系。
Android进阶——自定义View的必修课之关于Canvas绘图与Android坐标系的总结
Android自定义View基础-坐标系
自定义控件热身——View的坐标位置和大小详解
Android自定义View三(坐标系与View的绘制流程)
android坐标系详解
怎么获取到View的位置View.getLocationInWindow()的为0 -----介绍原因和一些特殊知识点
开发android中,解决View.getLocationOnScreen为0 -----文中所提到的另一种解决方案