Android View measure (三) 经常用法
ViewGroup.measureChild()
ViewGroup.measureChildWithMargins()
/**
* Ask one of the children of this view to measure itself, taking into
* account both the MeasureSpec requirements for this view and its padding
* and margins. The child must have MarginLayoutParams The heavy lifting is
* done in getChildMeasureSpec.
*
* @param child The child to measure
* @param parentWidthMeasureSpec The width requirements for this view
* @param widthUsed Extra space that has been used up by the parent
* horizontally (possibly by other children of the parent)
* @param parentHeightMeasureSpec The height requirements for this view
* @param heightUsed Extra space that has been used up by the parent
* vertically (possibly by other children of the parent)
*/
protected void measureChildWithMargins(View child,
int parentWidthMeasureSpec, int widthUsed,
int parentHeightMeasureSpec, int heightUsed) {
// 1 类型转换
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); // 2 getChildMeasureSpec方法
final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ widthUsed, lp.width);
final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+ heightUsed, lp.height); child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
此方法针对第一个參数传递的子视图进行Measure操作。
1. 传递的子视图LayoutParams必须是或者继承自MarginLayoutParams,否者会抛出转换异常
/**
* 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
*/
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.FILL_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.FILL_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.FILL_PARENT) {
// Child wants to be our size... find out how big it should
// be
resultSize = 0;
resultMode = MeasureSpec.UNSPECIFIED;
} else if (childDimension == LayoutParams.WRAP_CONTENT) {
// Child wants to determine its own size.... find out how
// big it should be
resultSize = 0;
resultMode = MeasureSpec.UNSPECIFIED;
}
break;
}
return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
}
protected void measureChildWithMargins(View child,
int parentWidthMeasureSpec, int widthUsed,
int parentHeightMeasureSpec, int heightUsed) { // 1 .... // 2 getChildMeasureSpec方法
final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ widthUsed, lp.width);
}
调用此方法处。看看这三个參数的详细含义。
1. spec : 此视图要求的规格 【parentWidthMeasureSpec】
2. padding : 当前ViewGroup视图的padding值与传入子视图的margin值 【mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin + widthUsed】?widthUsed
3. childDimension : 传入參数的视图,期望展示多大【lp.width】
** 举一个样例
扩展:MeasureSpec方法与拼接方式
/**
* Utility to reconcile a desired size with constraints imposed by a MeasureSpec.
* Will take the desired size, unless a different size is imposed by the constraints.
*
* @param size How big the view wants to be
* @param measureSpec Constraints imposed by the parent
* @return The size this view should be.
*/
public static int resolveSize(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:
result = Math.min(size, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
/**
* Creates a measure specification based on the supplied size and mode.
*
* The mode must always be one of the following:
* <ul>
* <li>{@link android.view.View.MeasureSpec#UNSPECIFIED}</li>
* <li>{@link android.view.View.MeasureSpec#EXACTLY}</li>
* <li>{@link android.view.View.MeasureSpec#AT_MOST}</li>
* </ul>
*
* @param size the size of the measure specification
* @param mode the mode of the measure specification
* @return the measure specification based on size and mode
*/
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}
/**
* <p>This mehod must be called by {@link #onMeasure(int, int)} to store the
* measured width and measured height. Failing to do so will trigger an
* exception at measurement time.</p>
*
* @param measuredWidth the measured width of this view
* @param measuredHeight the measured height of this view
*/
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight; mPrivateFlags |= MEASURED_DIMENSION_SET;
} /**
* The width of this view as measured in the most recent call to measure().
* This should be used during measurement and layout calculations only. Use
* {@link #getWidth()} to see how wide a view is after layout.
*
* @return The measured width of this view.
*/
public final int getMeasuredWidth() {
return mMeasuredWidth;
} /**
* The height of this view as measured in the most recent call to measure().
* This should be used during measurement and layout calculations only. Use
* {@link #getHeight()} to see how tall a view is after layout.
*
* @return The measured height of this view.
*/
public final int getMeasuredHeight() {
return mMeasuredHeight;
}
Android View measure (三) 经常用法的更多相关文章
- Android View.setId(int id) 用法
Android View.setId(int id) 用法 当要在代码中动态的添加View并且为其设置id时,如果直接用一个int值时,Studio会警告. 经过查询,动态设置id的方法有两种; 1. ...
- 简单研究Android View绘制三 布局过程
2015-07-28 17:29:19 这一篇主要看看布局过程 一.布局过程肯定要不可避免的涉及到layout()和onLayout()方法,这两个方法都是定义在View.java中,源码如下: /* ...
- Android View框架总结(四)View布局流程之Measure
View树的measure流程 View的measures时序图 View布局流程之measure measure过程 View的measure过程 ViewGroup的measure过程 Frame ...
- Android View 测量流程(Measure)完全解析
前言 上一篇文章,笔者主要讲述了DecorView以及ViewRootImpl相关的作用,这里回顾一下上一章所说的内容:DecorView是视图的顶级View,我们添加的布局文件是它的一个子布局,而V ...
- Android View框架的measure机制
概述 Android中View框架的工作机制中,主要有三个过程: 1.View树的測量(measure)Android View框架的measure机制 2.View树的布局(layout) Andr ...
- 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...
- Android View的绘制机制流程深入详解(三)
本系列文章主要着重深入介绍Android View的绘制机制及流程,第三篇主要介绍并分析视图状态以及重绘流程,首先剖析了 视图的几种状态,然后在深入分析视图的重绘机制流程. 真题园网:http://w ...
- Android自定义控件View(三)组合控件
不少人应该见过小米手机系统音量控制UI,一个圆形带动画效果的音量加减UI,效果很好看.它是怎么实现的呢?这篇博客来揭开它的神秘面纱.先上效果图 相信很多人都知道Android自定义控件的三种方式,An ...
- Android View视图系统分析和Scroller和OverScroller分析
Android View视图系统分析和Scroller和OverScroller分析 View 视图分析 首先,我们知道.在Android中全部的视图资源(无论是Layout还是V ...
随机推荐
- 如何让一个div里面的div垂直居中?
如何让一个div里面的div垂直居中? 如何让上面灰色有文字那个div和背景图标垂直居中,不管屏幕大小有好大,始终在垂直方向上的中间.上面有整个布局和样式表,谢谢高手指点 CSS3时代当然要用CSS3 ...
- swift Enumerations
swift Enumerations enum.case.switch CaseIterable allCases 要区别枚举变量和关联值 枚举变量参与枚举运算: 关联值和rawvalue不参与. A ...
- day15-模块的基础及导入
目录 模块 什么是模块 使用模块 import 循环导入问题 解决方案一 解决方案二 模块的搜索路径 Python文件的两种用途 包 导入包内包 导入包内包的模块 绝对导入与相对导入 绝对导入 相对导 ...
- mac系统,鼠标移动太慢
to check your speed: defaults read -g com.apple.mouse.scaling to set your speed defaults write -g co ...
- CAD得到0层上的所有实体(com接口VB语言)
主要用到函数说明: IMxDrawSelectionSet::Select 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARIA ...
- CAD控件:网上打开dwg文件时,对dwg文件路径加密的功能
梦想CAD控件2015.03.12最新更新 1. 增加控件状态栏文字,自定义功能, C++接口为 : CStatusBarInformationReactor::CreatePro ...
- 校内测之zay与银临 (day2)(只有T1)
一些与题目无关的碎碎念 推出式子来一定要化简!!!freopen不要写错!!!特判不要瞎搞!!!! 做到以上三点能高35分qwq T1 江城唱晚 你看数据那么大,显然又是一道数学题. 这里有n个种海棠 ...
- 题解 NOI2018 归程
题解 NOI2018 归程 题意 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l, ...
- Linux 源码
https://elixir.bootlin.com/linux/latest/source
- css实现圆角效果
源码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...