view设置gone的时候getHeight()的值
public final int getHeight() {
return mBottom - mTop;
}
是由mBottom和mTop决定的假定父控件parentView为linearLayout,子控件childView为View;
追踪到onLayout
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mOrientation == VERTICAL) {
layoutVertical(l, t, r, b);
} else {
layoutHorizontal(l, t, r, b);
}
}
2选1,看layoutVerticalvoid layoutVertical(int left, int top, int right, int bottom) {
...
else if (child.getVisibility() != GONE) {
...
setChildFrame(child, childLeft, childTop + getLocationOffset(child),childWidth, childHeight);
...
}
...
}GONE的时候,并不会调用setChildFrame,getHeight的值也就不会变
private void setChildFrame(View child, int left, int top, int width, int height) {
child.layout(left, top, left + width, top + height);
}
继续往下走,childView的layoutpublic void layout(int l, int t, int r, int b) {
...
boolean changed = isLayoutModeOptical(mParent) ?setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
...
}
private boolean setOpticalFrame(int left, int top, int right, int bottom) {
Insets parentInsets = mParent instanceof View ?
((View) mParent).getOpticalInsets() : Insets.NONE;
Insets childInsets = getOpticalInsets();
return setFrame(
left + parentInsets.left - childInsets.left,
top + parentInsets.top - childInsets.top,
right + parentInsets.left + childInsets.right,
bottom + parentInsets.top + childInsets.bottom);
}
setOpticalFrame最终也会调用setFrameprotected boolean setFrame(int left, int top, int right, int bottom) {
...
mTop = top;
mRight = right;
mBottom = bottom;
...
}
当一个View被设置为GONE时,它的getHeight()方法仍然会返回之前布局分配的高度。原因是GONE的View虽然不占用布局空间,但高度值在onLayout()中未被更新。在LinearLayout的onLayout()方法中,对于GONE的View不会调用setChildFrame(),因此高度保持不变。深入源码分析了View的layout()和setFrame()方法,揭示了这一行为的原因。
1033

被折叠的 条评论
为什么被折叠?



