测量自身宽高流程measure(widthMeasureSpec, heightMeasureSpec)-->
onMeasure(widthMeasureSpec, heightMeasureSpec)-->
setMeasuredDimension(width, height)-->
setMeasuredDimensionRaw(measureWidth, measureHeight)
调用结束,TextView宽高测量结束。
onMeasure(int widthMeasureSpec, int heightMeasureSpec)测量自身的宽高。测量完成以后通过setMeasuredDimension(int,int)设置给系统。setMeasuredDimension()是View类中的final方法,调用了方法setMeasuredDimensionRaw(measuredWidth, measuredHeight)至此调用链结束。
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
BoringLayout.Metrics boring = UNKNOWN_BORING;
BoringLayout.Metrics hintBoring = UNKNOWN_BORING;
if (mTextDir == null) {
mTextDir = getTextDirectionHeuristic();
}
int des = -1;
boolean fromexisting = false;
final float widthLimit = (widthMode == MeasureSpec.AT_MOST)
? (float) widthSize : Float.MAX_VALUE;
if (widthMode == MeasureSpec.EXACTLY) {
// Parent has told us how big to be. So be it.
width = widthSize;
} else {
if (mLayout != null && mEllipsize == null) {
des = desired(mLayout);
}
if (des < 0) {
boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
if (boring != null) {
mBoring = boring;
}
} else {
fromexisting = true;
}
if (boring == null || boring == UNKNOWN_BORING) {
if (des < 0) {
des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0,
mTransformed.length(), mTextPaint, mTextDir, widthLimit));
}
width = des;
} else {
width = boring.width;
}
final Drawables dr = mDrawables;
if (dr != null) {
width = Math.max(width, dr.mDrawableWidthTop);
width = Math.max(width, dr.mDrawableWidthBottom);
}
if (mHint != null) {
int hintDes = -1;
int hintWidth;
if (mHintLayout != null && mEllipsize == null) {
hintDes = desired(mHintLayout);
}
if (hintDes < 0) {
hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, mHintBoring);
if (hintBoring != null) {
mHintBoring = hintBoring;
}
}
if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
if (hintDes < 0) {
hintDes = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mHint, 0,
mHint.length(), mTextPaint, mTextDir, widthLimit));
}
hintWidth = hintDes;
} else {
hintWidth = hintBoring.width;
}
if (hintWidth > width) {
width = hintWidth;
}
}
width += getCompoundPaddingLeft() + getCompoundPaddingRight();
if (mMaxWidthMode == EMS) {
width = Math.min(width, mMaxWidth * getLineHeight());
} else {
width = Math.min(width, mMaxWidth);
}
if (mMinWidthMode == EMS) {
width = Math.max(width, mMinWidth * getLineHeight());
} else {
width = Math.max(width, mMinWidth);
}
// Check against our minimum width
width = Math.max(width, getSuggestedMinimumWidth());
if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(widthSize, width);
}
}
int want = width - getCompoundPaddingLeft() - getCompoundPaddingRight();
int unpaddedWidth = want;
if (mHorizontallyScrolling) want = VERY_WIDE;
int hintWant = want;
int hintWidth = (mHintLayout == null) ? hintWant : mHintLayout.getWidth();
if (mLayout == null) {
makeNewLayout(want, hintWant, boring, hintBoring,
width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
} else {
final boolean layoutChanged = (mLayout.getWidth() != want) || (hintWidth != hintWant)
|| (mLayout.getEllipsizedWidth()
!= width - getCompoundPaddingLeft() - getCompoundPaddingRight());
final boolean widthChanged = (mHint == null) && (mEllipsize == null)
&& (want > mLayout.getWidth())
&& (mLayout instanceof BoringLayout
|| (fromexisting && des >= 0 && des <= want));
final boolean maximumChanged = (mMaxMode != mOldMaxMode) || (mMaximum != mOldMaximum);
if (layoutChanged || maximumChanged) {
if (!maximumChanged && widthChanged) {
mLayout.increaseWidthTo(want);
} else {
makeNewLayout(want, hintWant, boring, hintBoring,
width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
}
} else {
// Nothing has changed
}
}
if (heightMode == MeasureSpec.EXACTLY) {
// Parent has told us how big to be. So be it.
height = heightSize;
mDesiredHeightAtMeasure = -1;
} else {
int desired = getDesiredHeight();
height = desired;
mDesiredHeightAtMeasure = desired;
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(desired, heightSize);
}
}
int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom();
if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) {
unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum));
}
/*
* We didn't let makeNewLayout() register to bring the cursor into view,
* so do it here if there is any possibility that it is needed.
*/
if (mMovement != null
|| mLayout.getWidth() > unpaddedWidth
|| mLayout.getHeight() > unpaddedHeight) {
registerForPreDraw();
} else {
scrollTo(0, 0);
}
//测量完成以后通过setMeasuredDimension(int,int)设置给系统
setMeasuredDimension(width, height);
}
}