您的位置:首页 > 移动开发 > Android开发

HorizontalScrollView重新layout之后自动滑动初始位置问题解决

2017-07-03 16:40 686 查看
HorizontalScrollView在重新layout时,有时候会自动滑动到其他位置,这是由于他的后代view获取到焦点导致的,来让我们从代码层面看清这个问题:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childWidth = 0;
int childMargins = 0;

if (getChildCount() > 0) {
childWidth = getChildAt(0).getMeasuredWidth();
LayoutParams childParams = (LayoutParams) getChildAt(0).getLayoutParams();
childMargins = childParams.leftMargin + childParams.rightMargin;
}

final int available = r - l - getPaddingLeftWithForeground() -
getPaddingRightWithForeground() - childMargins;

final boolean forceLeftGravity = (childWidth > available);

layoutChildren(l, t, r, b, forceLeftGravity);

mIsLayoutDirty = false;
// Give a child focus if it needs it
//就是在这一行,scrollView自动滑动到那个有焦点的view的位置
if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
scrollToChild(mChildToScrollTo);
}
mChildToScrollTo = null;

if (!isLaidOut()) {
final int scrollRange = Math.max(0,
childWidth - (r - l - mPaddingLeft - mPaddingRight));
if (mSavedState != null) {
mScrollX = isLayoutRtl()
? scrollRange - mSavedState.scrollOffsetFromStart
: mSavedState.scrollOffsetFromStart;
mSavedState = null;
} else {
if (isLayoutRtl()) {
mScrollX = scrollRange - mScrollX;
} // mScrollX default value is "0" for LTR
}
// Don't forget to clamp
if (mScrollX > scrollRange) {
mScrollX = scrollRange;
} else if (mScrollX < 0) {
mScrollX = 0;
}
}

// Calling this with the present values causes it to re-claim them
scrollTo(mScrollX, mScrollY);
}


而mChildToScrollTo这个view是在requestChildFocus中赋值的,

@Override
public void requestChildFocus(View child, View focused) {
if (!mIsLayoutDirty) {
scrollToChild(focused);
} else {
// The child may not be laid out yet, we can't compute the scroll yet
mChildToScrollTo = focused;
}
super.requestChildFocus(child, focused);
}


解决办法 :
覆写父类方法onLayout,就可以解决这个问题

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int tempScrollX = getScrollX();
super.onLayout(changed, l, t, r, b);
final int scrollX = getScrollX();

if (tempScrollX != scrollX) {
this.scrollTo(tempScrollX, 0);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android ScrollView
相关文章推荐