View坐标系

View坐标系_第1张图片
1-1View坐标系

View坐标系_第2张图片
1-2父View移出屏幕后子View的getLeft()值

1.View静态坐标

View坐标 参数含义
Left = getLeft(); View自身左侧到父View左侧的距离
Top = getTop(); View自身顶部到父View顶部的距离
Right = getRight(); View自身右侧到父View左侧的距离
Bottom = getBottom(); View自身底部到父View顶部的距离
getTranslationX() View左上角相对父View的X轴偏移量
getTranslationY() View左上角相对父View的Y轴偏移量
getX() 值为getLeft()+getTranslationX(),当setTranslationX()时getLeft()不变,getX()变。
getY() 值为getTop()+getTranslationY(),当setTranslationY()时getTop()不变,getY()变。

MotionEvent触摸事件坐标、

MotionEvent坐标方法 参数含义
getX() 当前触摸点距离当前View自身左边的距离
getY() 当前触摸点距离当前View自身顶部的距离
getRawX() 当前触摸点距离屏幕左边的距离(Android绝对坐标系)
getRawY() 当前触摸点距离屏幕顶部的距离(Android绝对坐标系)

2.View中的滑动坐标系

View坐标系_第3张图片
Paste_Image.png
View滑动坐标 参数含义
offsetLeftAndRight(int offset) 水平方向挪动View,offset为正则x轴正向移动,移动的是整个View,getLeft()会变的,自定义View很有用
offsetTopAndBottom(int offset) 垂直方向挪动View,offset为正则y轴正向移动,移动的是整个View,getTop()会变的,自定义View很有用
scrollTo(int x, int y) View中内容(不是整个View)滑动到相应的位置,参考坐标原点为ParentView左上角,x,y为正则向xy轴反方向移动,反之同理。
scrollBy(int x, int y) 在scrollTo()的基础上继续滑动xy。
setScrollX(int value) 实质为scrollTo(),只是改变X轴滑动。
setScrollY(int value) 实质为scrollTo(),只是改变Y轴滑动。
getScrollX()/getScrollY() 获取当前滑动位置偏移量。分别对应着mScrollX、mScrollY。mScrollX的值总是等于View左边缘和View内容左边缘在水平方向的距离,mScrollY的值总是等于View的上边缘和View内容上边缘在竖直方向的距离。View边缘指View的位置,有四个顶点组成,Left、Top、Right、Bottom。所以该值的参考坐标系是父View的左上角。

mScrollX = getLeft()-mContentDistanceX;
mScrollY = getTop()-mContentDistanceY;

(mContentDistanceX和mContentDistanceY分别是View的内容在X轴、Y轴滑动的距离)
mScrollX和mScrollY的单位为像素,并且当View左边缘(getLeft())在View内容左边缘的右边时,mScrollX为正值,反之为负值;当View上边缘(getTop())在View内容上边缘的下边时,mScrollY为正值,反之为负值。
同理,调用View的scrollBy()和scrollTo()方法时参数传递正数,却想坐标系负方向移动。
源码分析:

public void scrollTo(int x, int y) {
    if (mScrollX != x || mScrollY != y) {
        int oldX = mScrollX; 
        int oldY = mScrollY; 
        mScrollX = x; 
        mScrollY = y; 
        invalidateParentCaches(); 
        onScrollChanged(mScrollX, mScrollY, oldX, oldY); 
        if (!awakenScrollBars()) {
             postInvalidateOnAnimation();
         } 
    }
}

View的该方法注释里明确说明了调运他会触发onScrollChanged()和invalidated()方法,那我们就将矛头转向invalidated()方法触发的draw()过程,draw()过程中最终其实会触发下面的invalidate()方法,如下:

public void invalidate(int l, int t, int r, int b) {
    final int scrollX = mScrollX;
    final int scrollY = mScrollY; //scroller时为何参数和坐标反向的真实原因
    invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
}

invalidate()的四个参数分别是View的Left、Top、Right和Bottom,代码中mScrollX和mScrollY。l-scrollX,当scrollX为负时,l-scrollx > l,此时View内容的左边缘在view左边缘的右侧,同理说明scrollX、scrollY传负值时,View的内容往坐标系正值方向移动。

你可能感兴趣的:(View坐标系)