scrollTo()和scrollBy()都能让View中的内容瞬间移动到一个新的位置。
从命名来看,to有到达的意思,by有经过的意思。
所以scrollTo()只会偏移一次,scrollBy()会一直偏移。
但具体区别如下:
/*
scrollTo(int x, int y):滚动到
相对于坐标系原点移动
scrollBy(int x, int y):滚动了
相对于当前位置移动
*/
首先必须清楚scrollTo(int x,int y)和scrollBy(int x,int y)中的x和y都表示偏移量,而不是坐标,因此偏移量有正有负,正数表示View向负坐标系移动,负数表示往正坐标系移动,偏移量的计算为:
偏移量 = 起始坐标 - 终点坐标。
/*
值为正则向负坐标系偏移,值为负向正坐标系偏移
mScrollX:表示水平方向上的偏移量,不是坐标,
mScrollY:表示垂直方向上的偏移量,不是坐标
*/
protected int mScrollX;
protected int mScrollY;
scrollBy():
在scrollBy()方法内部是调用了scrollTo()方法,表示相对于当前偏移量mScrollX和mScrollY的基础上再继续偏移x和y。
如果一个View要在X轴正方向和Y轴正方向都偏移100的距离,那么查看scrollTo()方法内部实现时,当初始时mScrollX,mScrollY都为0,在X和Y轴正方向上都偏移100的距离以后,mScrollX的值就为(0-100),同理mScrollY的值为(0-100),下次又要偏移100的距离,发现mScrollX和x的值相同,则不会再继续偏移。
/*
其中x,y表示偏移量,而不是指坐标。
偏移量为:起始坐标减去终点坐标。
如:从(0,0)移动到(100,100),
偏移量为:水平偏移量(0-100),垂直偏移量(0-100)
*/
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();
}
}
}
而对于scrollBy(),就算mScrollX和x相同,但是其内部是调用scrollTo(mScrollX+x,mScrollY+y),传入的参数是在原偏移mScrollX和mScrollY的基础上再加上x和y,所以就表示相对于当前偏移再发生偏移。
/*
表示在偏移为(mScrollX,mScrollY)的基础上再偏移x,y
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
总之,scrollTo()只会偏移一次,而scrollBy()会一直发生偏移。