美文网首页
View坐标系

View坐标系

作者: BangAiN | 来源:发表于2016-07-31 13:25 被阅读494次
    1-1View坐标系
    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中的滑动坐标系

    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坐标系

          本文链接:https://www.haomeiwen.com/subject/mhutsttx.html