用到scrollview的时候发现scrollTo有时候无效,故查看了下源码:
/**
* {@inheritDoc}
*
* <p>This version also clamps the scrolling to the bounds of our child.
*/
@Override
public void scrollTo(int x, int y) {
// we rely on the fact the View.scrollBy calls scrollTo.
if (getChildCount() > 0) {
View child = getChildAt(0);
x = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
y = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
if (x != mScrollX || y != mScrollY) {
super.scrollTo(x, y);
}
}
}
分析估计是if (x != mScrollX || y != mScrollY) {
super.scrollTo(x, y);
}
if判断没通过,查看clamp方法:
private static int clamp(int n, int my, int child) {
if (my >= child || n < 0) {
return 0;
}
if ((my + n) > child) {
return child - my;
}
return n;
}
追溯到父类里面查看
mScrollX,mScrollY 的初始化:
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没有加载完成前mPaddingRight,mPaddingLeft等都为空,导致
if (x != mScrollX || y != mScrollY) {
super.scrollTo(x, y);
}
不成立,故view没加载完成前不调用super.scrollTo(x, y);
解决办法:
ViewTreeObserver vto = scrollView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
mainScroll.scrollTo(0, 0);
}
});
当全局布局发生改变或者视图树中的某个视图的可视状态发生改变时会调用这个回调函数。此时在执行
scrollTo()方法即可