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.pngView滑动坐标 | 参数含义 |
---|---|
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的内容往坐标系正值方向移动。
网友评论