文章标题

来源:互联网 发布:淘宝怎么差评改好评 编辑:程序博客网 时间:2024/06/07 07:57

ViewGroup.java
/**
* Ask all of the children of this view to measure themselves, taking into
* account both the MeasureSpec requirements for this view and its padding.
* We skip children that are in the GONE state The heavy lifting is done in
* getChildMeasureSpec.
*
* @param widthMeasureSpec The width requirements for this view
* @param heightMeasureSpec The height requirements for this view
*/
/**
测量所有子view测量规格,子view测量规格右父viewgroup测量规格以及子view自身布局参数决定
*/
protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {
final int size = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < size; ++i) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
}

/**
* Ask one of the children of this view to measure itself, taking into
* account both the MeasureSpec requirements for this view and its padding.
* The heavy lifting is done in getChildMeasureSpec.
*
* @param child The child to measure
* @param parentWidthMeasureSpec The width requirements for this view
* @param parentHeightMeasureSpec The height requirements for this view
* 子view测量规格右父viewGroup测量规格以及自身padding,布局参数layout_width, layout_height决定
*/
protected void measureChild(View child, int parentWidthMeasureSpec,
int parentHeightMeasureSpec) {
final LayoutParams lp = child.getLayoutParams();

    final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,            mPaddingLeft + mPaddingRight, lp.width);    final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,            mPaddingTop + mPaddingBottom, lp.height);    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);}

/**
* Does the hard part of measureChildren: figuring out the MeasureSpec to
* pass to a particular child. This method figures out the right MeasureSpec
* for one dimension (height or width) of one child view.
*
* The goal is to combine information from our MeasureSpec with the
* LayoutParams of the child to get the best possible results. For example,
* if the this view knows its size (because its MeasureSpec has a mode of
* EXACTLY), and the child has indicated in its LayoutParams that it wants
* to be the same size as the parent, the parent should ask the child to
* layout given an exact size.
*
* @param spec The requirements for this view
* @param padding The padding of this view for the current dimension and
* margins, if applicable
* @param childDimension How big the child wants to be in the current
* dimension
* @return a MeasureSpec integer for the child

    *当viewgroup测量规格mode为MeasureSpec.EXACTLY:      也就是说viewgroup测量规格已经确定,大小为MeasureSpec.getSize(spec)      若子view布局参数为match_parent,则子view测量规格和viewgroup一样      若子view布局参数为wrap_content,则子view测量规格为size, AT_MOST      若子view布局参数为准确数值,则为该数值+MeasureSpec.EXACTLY      当viewgroup测量规格mode为MeasureSpec.AT_MOST:      也就是说viewgroup大小没有确定,最大值为MeasureSpec.getSize(spec)      若子view布局参数为match_parent,则和viewgroup一样为size+MeasureSpec.AT_MOST      若子view布局参数为wrap_parent,则和viewgroup一样为size+MeasureSpec.AT_MOST      若子view布局参数为准确数值,则为该数值+MeasureSpec.EXACTLY */public static int getChildMeasureSpec(int spec, int padding, int childDimension) {    int specMode = MeasureSpec.getMode(spec);    int specSize = MeasureSpec.getSize(spec);    int size = Math.max(0, specSize - padding);    int resultSize = 0;    int resultMode = 0;    switch (specMode) {    // Parent has imposed an exact size on us    case MeasureSpec.EXACTLY:        if (childDimension >= 0) {            resultSize = childDimension;            resultMode = MeasureSpec.EXACTLY;        } else if (childDimension == LayoutParams.MATCH_PARENT) {            // Child wants to be our size. So be it.            resultSize = size;            resultMode = MeasureSpec.EXACTLY;        } else if (childDimension == LayoutParams.WRAP_CONTENT) {            // Child wants to determine its own size. It can't be            // bigger than us.            resultSize = size;            resultMode = MeasureSpec.AT_MOST;        }        break;    // Parent has imposed a maximum size on us    case MeasureSpec.AT_MOST:        if (childDimension >= 0) {            // Child wants a specific size... so be it            resultSize = childDimension;            resultMode = MeasureSpec.EXACTLY;        } else if (childDimension == LayoutParams.MATCH_PARENT) {            // Child wants to be our size, but our size is not fixed.            // Constrain child to not be bigger than us.            resultSize = size;            resultMode = MeasureSpec.AT_MOST;        } else if (childDimension == LayoutParams.WRAP_CONTENT) {            // Child wants to determine its own size. It can't be            // bigger than us.            resultSize = size;            resultMode = MeasureSpec.AT_MOST;        }        break;    // Parent asked to see how big we want to be    case MeasureSpec.UNSPECIFIED:        if (childDimension >= 0) {            // Child wants a specific size... let him have it            resultSize = childDimension;            resultMode = MeasureSpec.EXACTLY;        } else if (childDimension == LayoutParams.MATCH_PARENT) {            // Child wants to be our size... find out how big it should            // be            resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;            resultMode = MeasureSpec.UNSPECIFIED;        } else if (childDimension == LayoutParams.WRAP_CONTENT) {            // Child wants to determine its own size.... find out how            // big it should be            resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;            resultMode = MeasureSpec.UNSPECIFIED;        }        break;    }    //noinspection ResourceType    return MeasureSpec.makeMeasureSpec(resultSize, resultMode);}/**    子view setMeasuredDimension*/

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

/**    子view 大小基本上就是MeasureSpec.getSize(measureSpec)*/

public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

    switch (specMode) {    case MeasureSpec.UNSPECIFIED:        result = size;        break;    case MeasureSpec.AT_MOST:    case MeasureSpec.EXACTLY:        result = specSize;        break;    }    return result;}
0 0
原创粉丝点击