Android坐标分析过程

本文详细解析了Android中的Android坐标系和视图坐标系,包括它们的定义、获取坐标值的方法。介绍了View的getLocationOnScreen()、getLocationInWindow()以及MotionEvent的getRawX()、getRawY()等方法在坐标获取中的应用。同时,阐述了视图坐标系以父视图左上角为原点的特点,并列举了相关API如getTop()、getLeft()、getX()、getY()等用于获取视图位置和距离。
摘要由CSDN通过智能技术生成

Android中有两种坐标系,分别是Android坐标系和视图坐标系。
首先看一下屏幕区域划分
这里写图片描述

//获取状态栏高度
Rect rect= new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rectangle.top;

//获取应用程序App区域宽高等尺寸
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);

//获取View布局区域宽高等尺寸
Rect rect = new Rect();  
getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(rect);  

//获取获取屏幕区域的宽高等尺寸
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;

1 Android坐标系

在Android中,将屏幕的最左上角顶点作为Android坐标系的原点;从原点向右是X轴的正方向,从原点向下是Y轴的正方向,如图所示:
这里写图片描述
(1) View提供了getLocationOnScreen( int[] location)方法来获取在整个屏幕内的绝对坐标,此坐标值为View左上角的坐标,源码如下:

public void getLocationOnScreen(@Size(2) int[] location) {
        getLocationInWindow(location);

        final AttachInfo info = mAttachInfo;
        if (info != null) {
            location[0] += info.mWindowLeft;
            location[1] += info.mWindowTop;
        }
}

在传入的int[]数组中,location[0]代表的是X轴坐标,location[1]代表的Y轴坐标。
特别注意的是该View的坐标值是从屏幕左上角开始获取的,因此也包括了通知栏的高度
(2) View也提供了getLocationInWindow()方法,它获取View在当前窗口内的绝对坐标,源码如下:

public void getLocationInWindow(@Size(2) int[] location) {
        if (location == null || location.length < 2) {
            throw new IllegalArgumentException("location must be an array of two integers");
        }

        if (mAttachInfo == null) {
            // When the view is not attached to a window, this method does not make sense
            location[0] = location[1] = 0;
            return;
        }

        float[] position = mAttachInfo.mTmpTransformLocation;
        position[0] = position[1] = 0.0f;

        if (!hasIdentityMatrix()) {
            getMatrix().mapPoints(position);
        }

        position[0] += mLeft;
        position[1] += mTop;

        ViewParent viewParent = mParent;
        while (viewParent instanceof View) {
            final View view = (View) viewParent;

            position[0] -= view.mScrollX;
            position[1] -= view.mScrollY;

            if (!view.hasIdentityMatrix()) {
                view.getMatrix().mapPoints(position);
            }

            position[0] += view.mLeft;
            position[1] += view.mTop;

            viewParent = view.mParent;
         }

        if (viewParent instanceof ViewRootImpl) {
            // *cough*
            final ViewRootImpl vr = (ViewRootImpl) viewParent;
            position[1] -= vr.mCurScrollY;
        }

        location[0] = (int) (position[0] + 0.5f);
        location[1] = (int) (position[1] + 0.5f);
    }

(3) 通过MotionEvent类中的getRawX(),getRawY()方法获取的坐标就是以这个坐标系为标准下的坐标值。

2 视图坐标系

Android中的视图坐标系,是子视图与其父视图中的位置关系。与Android坐标系一样,视图坐标系也是以原点向右为X轴正方向,以原点向下为Y轴正方向。和Android坐标系不同的是,视图坐标系的原点是以父视图左上角的位置为原点。如果所示:
这里写图片描述
如上图所示,对于“黑色的触摸点”来说,父视图View左上角就是视图坐标系的原点(0,0)。通过MotionEvent类中的getX()、getY()方法所获得视图坐标系的坐标。

3 获取坐标值以及相对距离

这里写图片描述
最外层的是手机屏幕,中间层的是ViewGroup,最内层的是ViewGroup中放置的view。
上图中标注的方法可以分为两类,一类是View提供的方法,一类是MotionEvent提供的方法。

View的静态坐标方法(View提供的API)

getTop() 获取到的是view自身的顶边到其父布局顶边的距离;
getLeft() 获取到的是view自身的左边到其父布局左边的距离;
getRight() 获取到的是view自身的右边到其父布局左边的距离;
getBottom() 获取到的是view自身底边到其父布局顶边的距离;
getX() 获取到的是getLeft()+getTranslationX(),当setTranslationX()时getLeft()不变,getX()变;
getY() 获取到的是getTop()+getTranslationY(),当setTranslationY()时getTop()不变,getY()变;

MotionEvent坐标方法(MotionEvent提供的API )

getX() 获取点击事件距离控件左边的距离,即视图坐标;
getY() 获取点击事件距离控件顶边的距离,即视图坐标;
getRawX() 获取到的是点击事件距离整个屏幕左边的距离,即绝对坐标;
getRawY() 获取到的是点击事件距离整个屏幕顶边的距离,即绝对坐标;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值