截取MeasureSpec类的源代码出来看看
/** * A MeasureSpec encapsulates the layout requirements passed from parent to child. * Each MeasureSpec represents a requirement for either the width or the height. * A MeasureSpec is comprised of a size and a mode. There are three possible * modes: * <dl> * <dt>UNSPECIFIED</dt> * <dd> * The parent has not imposed any constraint on the child. It can be whatever size * it wants. * </dd> * * <dt>EXACTLY</dt> * <dd> * The parent has determined an exact size for the child. The child is going to be * given those bounds regardless of how big it wants to be. * </dd> * * <dt>AT_MOST</dt> * <dd> * The child can be as large as it wants up to the specified size. * </dd> * </dl> * * MeasureSpecs are implemented as ints to reduce object allocation. This class * is provided to pack and unpack the <size, mode> tuple into the int. */ public static class MeasureSpec { private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT; /** * Measure specification mode: The parent has not imposed any constraint * on the child. It can be whatever size it wants. */ public static final int UNSPECIFIED = 0 << MODE_SHIFT; /** * Measure specification mode: The parent has determined an exact size * for the child. The child is going to be given those bounds regardless * of how big it wants to be. */ public static final int EXACTLY = 1 << MODE_SHIFT; /** * Measure specification mode: The child can be as large as it wants up * to the specified size. */ public static final int AT_MOST = 2 << MODE_SHIFT; /** * 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> * * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's * implementation was such that the order of arguments did not matter * and overflow in either value could impact the resulting MeasureSpec. * {@link android.widget.RelativeLayout} was affected by this bug. * Apps targeting API levels greater than 17 will get the fixed, more strict * behavior.</p> * * @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) { if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { return (size & ~MODE_MASK) | (mode & MODE_MASK); } } /** * Like {@link #makeMeasureSpec(int, int)}, but any spec with a mode of UNSPECIFIED * will automatically get a size of 0. Older apps expect this. * * @hide internal use only for compatibility with system widgets and older apps */ public static int makeSafeMeasureSpec(int size, int mode) { if (sUseZeroUnspecifiedMeasureSpec && mode == UNSPECIFIED) { return 0; } return makeMeasureSpec(size, mode); } /** * Extracts the mode from the supplied measure specification. * * @param measureSpec the measure specification to extract the mode from * @return {@link android.view.View.MeasureSpec#UNSPECIFIED}, * {@link android.view.View.MeasureSpec#AT_MOST} or * {@link android.view.View.MeasureSpec#EXACTLY} */ public static int getMode(int measureSpec) { return (measureSpec & MODE_MASK); } /** * Extracts the size from the supplied measure specification. * * @param measureSpec the measure specification to extract the size from * @return the size in pixels defined in the supplied measure specification */ public static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK); } static int adjust(int measureSpec, int delta) { final int mode = getMode(measureSpec); int size = getSize(measureSpec); if (mode == UNSPECIFIED) { // No need to adjust size for UNSPECIFIED mode. return makeMeasureSpec(size, UNSPECIFIED); } size += delta; if (size < 0) { Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size + ") spec: " + toString(measureSpec) + " delta: " + delta); size = 0; } return makeMeasureSpec(size, mode); } /** * Returns a String representation of the specified measure * specification. * * @param measureSpec the measure specification to convert to a String * @return a String with the following format: "MeasureSpec: MODE SIZE" */ public static String toString(int measureSpec) { int mode = getMode(measureSpec); int size = getSize(measureSpec); StringBuilder sb = new StringBuilder("MeasureSpec: "); if (mode == UNSPECIFIED) sb.append("UNSPECIFIED "); else if (mode == EXACTLY) sb.append("EXACTLY "); else if (mode == AT_MOST) sb.append("AT_MOST "); else sb.append(mode).append(" "); sb.append(size); return sb.toString(); } }
这里我介绍一点点MeasureSpec类的知识,源码是这样注释的:
A MeasureSpec encapsulates the layout requirements passed from parent to child.
意思是说,一个MeasureSpec封装了从parent view传递到 child view 的布局要求。
在自定义view 的时候,有时候需要重写onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法。事实上参数widthMeasureSpec就是父布局传递过来的一个MeasureSpec
比如onMeasure的参数widthMeasureSpec这个值由高2位和低30位组成,高2位保存的值叫specMode,可以通过MeasureSpec.getMode()获取;低30位为specSize,同样可以由MeasureSpec.getSize()获取。
我是如何知道高2位和低30位这些信息的呢?请看如下代码:
public static int getMode(int measureSpec) { return (measureSpec & MODE_MASK); }
获取Mode的时候,直接用一个与的位运算来得到Mode,再看MODE_MASK的定义:
private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT;
MODE_MASK是一个16进制的3左移30位得到的结果,就是也就是11000000000.....0000000000000(30个零)
相关推荐
MeasureSpec类提供了静态方法来创建和解析MeasureSpec。例如,可以通过`MeasureSpec.makeMeasureSpec(int size, int mode)`创建一个MeasureSpec对象,其中size参数是测量大小,mode参数是测量模式。`MeasureSpec....
Android提供了MeasureSpec类来辅助测量,这个类包含了一个模式(MODE)和一个大小(SIZE)两个部分,用于描述父视图对子视图尺寸的要求。 1. **MeasureSpec模式**: - EXACTLY:表示父视图已经指定了一个确切的...
测量规则遵循MeasureSpec类中的模式。 5. **布局更新**:通过重写onLayout()方法,可以自定义控件的布局位置,这在创建自定义 ViewGroup 类时尤为重要。 6. **触摸事件处理**:通过覆盖onTouchEvent()方法,可以...
这个方法决定了View的宽高,通常会使用MeasureSpec类提供的计算规则。我们需要确保View的尺寸能够适应其内容并满足父容器的约束。 ```java @Override protected void onMeasure(int widthMeasureSpec, int ...
理解MeasureSpec类及其工作原理是正确布局的关键。 五、动画与触摸事件 Android提供了多种动画机制,如Property Animation和View Animation,可用于自定义控件的动态效果。同时,自定义控件需要处理触摸事件,通常...
在measure过程中,父视图会通过MeasureSpec类向子视图传递测量规格。MeasureSpec提供了三种模式:UNSPECIFIED、EXACTLY和AT_MOST。UNSPECIFIED模式意味着父视图不对子视图有任何约束,子视图可以自由发展到期望的...
MeasureSpec类提供了测量模式和大小,开发者需要根据MeasureSpec提供的信息来计算并设置View的尺寸。 4. **布局(Layout)过程**:自定义View也需要处理布局过程,通常通过重写onLayout()方法来确定子视图的位置。此...
通常会使用MeasureSpec类来处理测量规则。 ```java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int ...
使用MeasureSpec类提供的方法可以帮助我们处理测量模式和大小。 3. **onLayout()**:如果我们的自定义View需要管理子视图,那么我们需要在这个方法中设置子视图的位置。不过,对于不包含子视图的简单自定义View,...
这可能涉及到MeasureSpec类的使用,它是Android系统用来传递测量规格给View及其子View的重要工具。 3. 布局更新:当新的按钮被添加或移除时,FlowLayout需要重新计算并布局所有的子View。这可能涉及到监听器的设置...
你可以使用MeasureSpec类提供的常量来获取父视图的约束条件,并根据这些条件计算出合适的尺寸。 四、触摸事件处理 自定义View可以通过重写`onTouchEvent()`来处理触摸事件。ACTION_DOWN、ACTION_UP、ACTION_MOVE等...
理解MeasureSpec类以及如何计算合适的尺寸至关重要。 5. **触摸事件处理**:通过覆盖`onTouchEvent()`方法,可以处理用户触摸屏幕的动作。通常需要处理ACTION_DOWN、ACTION_MOVE和ACTION_UP等事件,实现交互效果。 ...
Android提供MeasureSpec类帮助处理父视图传递的尺寸约束。 4. **事件处理** 自定义控件可以重写`onTouchEvent()`来处理触摸事件,`onHoverEvent()`处理悬浮事件,`onKeyDown()`和`onKeyUp()`处理键盘事件。理解...
这里可能需要用到MeasureSpec类,它提供了处理父视图对子视图尺寸约束的机制。 3. `onLayout()`方法:在此方法中,你需要确定每个子视图的位置。当一行无法容纳更多的子视图时,需要开始新的一行。可以维护一个变量...
这涉及到Android的MeasureSpec类,用于传递父视图对子视图的尺寸约束。 5. **数据加载与监听**:当用户滚动到底部时,需要加载更多数据。可以通过RecyclerView的addOnScrollListener()方法添加滚动监听器,然后在`...
介绍如何自定义View,并重写onMeasure方法重新测量高度和宽度, 讲解MeasureSpec类的使用方法 详见博文 http://blog.csdn.net/a87b01c14/article/details/50359226
MeasureSpec类是Android中用于存储测量模式和大小的类。它将测量模式和大小存储在一个int类型的变量中,前2位为模式,而后30位为大小。 在测量过程中,View需要重写onMeasure()方法,该方法会将MeasureSpec对象作为...
测量阶段的核心工具是MeasureSpec类。MeasureSpec包含了一个32位的整数,高2位表示测量模式,低30位表示测量大小。测量模式有三种: 1. EXACTLY:精确值模式,通常发生在layout_width或layout_height被设置为具体...
在Android中,这个“眼睛”就是MeasureSpec类,它提供了精确的测量指导。 MeasureSpec是一个32位的整数,包含两种信息: 1. 高2位表示测量模式(MeasureSpec Mode),有三种模式: - EXACTLY:精确模式,当View的...