自定义View(一) getMeasuredWidth和getWidth区别
程序员文章站
2022-05-04 11:29:36
...
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;
}
MEASURED_SIZE_MASK是固定的,我们看下mMeasuredWidth 值从哪来
private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
setMeasuredDimensionRaw是在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);
}
而setMeasuredDimension()是在onMeasure()调用,所以,我们知道了getMeasuredWidth()是在onMeasure()中设置得到的
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 值从哪来
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;
mDefaultFocusHighlightSizeChanged = true;
if (mForegroundInfo != null) {
mForegroundInfo.mBoundsChanged = true;
}
notifySubtreeAccessibilityStateChangedIfNeeded();
}
return changed;
}
而setFrame()在layout()中调用
@SuppressWarnings({"unchecked"})
public void layout(int l, int t, int r, int b) {
if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
int oldL = mLeft;
int oldT = mTop;
int oldB = mBottom;
int oldR = mRight;
boolean changed = isLayoutModeOptical(mParent) ?
//调用setFrame()
setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
......
}
现在我们就知道了getWidth()的值是在layout中设置了left和right后才能得到
上一篇: View 的工作原理
推荐阅读
-
Android之View的知识(getWidth() 和getMeasuredWidth区别 如何在oncreate获取宽高)
-
View的getWidth/getHeight与getMeasuredWidth/getMeasuredHeight的区别
-
前奏:自定义View(一)onDraw()中一些常用的属性和方法总结
-
Android自定义View5--getWidth()和getMeasuredWidth()区别, view.post(Runnable)引发内存泄漏的原因和解决
-
Android开发学习笔记——自定义View(一)View三大工作流程measure、layout和draw
-
自定义View(一) getMeasuredWidth和getWidth区别
-
getWidth()和getMeasuredWidth()的区别
-
前奏:自定义View(一)onDraw()中一些常用的属性和方法总结
-
Android自定义View5--getWidth()和getMeasuredWidth()区别, view.post(Runnable)引发内存泄漏的原因和解决