从源代码的角度发现:
1.对于-getMeasuredWidth打开源码发现
**
* Like {
@link
#getMeasuredWidthAndState()}, but only returns the
* raw width component (that is the result is masked by
* {
@link
#MEASURED_SIZE_MASK}).
*
*
@return
The raw measured width of this view.
*/
public final int
getMeasuredWidth
() {
return
mMeasuredWidth
&
MEASURED_SIZE_MASK
;
}
这里我们看到它的返回值与mMeasuredWidth相关,这个mMeasuredWidth是哪儿来的呢?
看源码
setMeasuredDimension:
protected final void
setMeasuredDimension
(
int
measuredWidth
, int
measuredHeight) {
boolean
optical =
isLayoutModeOptical
(
this
)
;
if
(optical !=
isLayoutModeOptical
(
mParent
)) {
Insets insets = getOpticalInsets()
;
int
opticalWidth = insets.left + insets.right
;
int
opticalHeight = insets.top + insets.bottom
;
measuredWidth += optical ? opticalWidth : -opticalWidth
;
measuredHeight += optical ? opticalHeight : -opticalHeight
;
}
setMeasuredDimensionRaw(measuredWidth
,
measuredHeight)
;
}
其中 setMeasuredDimensionRaw(源码:
private void
setMeasuredDimensionRaw
(
int
measuredWidth
, int
measuredHeight) {
mMeasuredWidth
= measuredWidth
;
mMeasuredHeight
= measuredHeight
;
mPrivateFlags
|=
PFLAG_MEASURED_DIMENSION_SET
;
}
所以可以得等到
getMeasuredWidth实际上是从setMeasuredDimension()中传递过来的参数
2.对于getWidth
/** * Return the width of the your view. * * @return The width of your view, in pixels. */ @ViewDebug.ExportedProperty(category = "layout") public final int getWidth() { return mRight - mLeft; }可以发现结果与
mRight - mLeft;有关那么这两个变量来自哪里呢?接着看源码发现 其实它是onlayout过程传过来的四个参数中的两个,那还等什么去看看
onlayout源码
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { } /** * Assign a size and position to this view. * * This is called from layout. * * @param left Left position, relative to parent * @param top Top position, relative to parent * @param right Right position, relative to parent * @param bottom Bottom position, relative to parent * @return true if the new size and position are different than the * previous ones * {@hide} */ protected boolean setFrame(int left, int top, int right, int bottom) { boolean changed = false; if (DBG) { Log.d("View", this + " View.setFrame(" + left + "," + top + "," + right + "," + bottom + ")"); } if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { changed = true; // Remember our drawn bit int drawn = mPrivateFlags & PFLAG_DRAWN; int oldWidth = mRight - mLeft; int oldHeight = mBottom - mTop; int newWidth = right - left; int newHeight = bottom - top; boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight); // Invalidate our old position invalidate(sizeChanged); mLeft = left; mTop = top; mRight = right; mBottom = bottom; mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); mPrivateFlags |= PFLAG_HAS_BOUNDS; if (sizeChanged) { sizeChange(newWidth, newHeight, oldWidth, oldHeight); } if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null) { // If we are visible, force the DRAWN bit to on so that // this invalidate will go through (at least to our parent). // This is because someone may have invalidated this view // before this call to setFrame came in, thereby clearing // the DRAWN bit. mPrivateFlags |= PFLAG_DRAWN; invalidate(sizeChanged); // parent display list may need to be recreated based on a change in the bounds // of any child invalidateParentCaches(); } // Reset drawn bit to original value (invalidate turns it off) mPrivateFlags |= drawn; mBackgroundSizeChanged = true; if (mForegroundInfo != null) { mForegroundInfo.mBoundsChanged = true; } notifySubtreeAccessibilityStateChangedIfNeeded(); } return changed; }到这里我们找到了getWidth方法的返回值的两个参数①mRight②mLeft。这样大家明白了getWidth返回值了吗?
综述:
①getMeasuredWidth方法获得的值是setMeasuredDimension方法设置的值,它的值在measure方法运行后就会确定
②getWidth方法获得是layout方法中传递的四个参数中的mRight-mLeft,它的值是在layout方法运行后确定的
③一般情况下在onLayout方法中使用getMeasuredWidth方法,而在除onLayout方法之外的地方用getWidth方法。