lp 其实就是上个博客提到的Window Attribute 只不过是ViewRoot的。
childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
desiredWindowWidth 根据代码可知,一般情况就是屏幕的宽度;desiredWindowHeight 根据代码可知,一般情况就是屏幕的宽度-状态栏高度;
/**
* Figures out the measure spec for the root view in a window based on it's
* layout params.
*
* @param windowSize
* The available width or height of the window
*
* @param rootDimension
* The layout params for one dimension (width or height) of the
* window.
*
* @return The measure spec to use to measure the root view.
*/
private int getRootMeasureSpec(int windowSize, int rootDimension) {
int measureSpec;
switch (rootDimension) {
case ViewGroup.LayoutParams.MATCH_PARENT:
// Window can't resize. Force root view to be windowSize.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
break;
case ViewGroup.LayoutParams.WRAP_CONTENT:
// Window can resize. Set max size for root view.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
break;
default:
// Window wants to be an exact size. Force root view to be that size.
measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
break;
}
return measureSpec;
}
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
注意ViewRoot并不是View,不过是ViewParent。刷新屏幕都是在这个类中,host就是PhoneWindow的DecorView。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
/**
* Utility to return a default size. Uses the supplied size if the
* MeasureSpec imposed no contraints. Will get larger if allowed
* by the MeasureSpec.
*
* @param size Default size for this view
* @param measureSpec Constraints imposed by the parent
* @return The size this view should be.
*/
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;
}
分享到:
相关推荐
View 的 onMeasure 方法默认行为是当模式为 UNSPECIFIED 时,设置尺寸为 mMinWidth(通常为 0)或者背景 drawable 的最小尺寸,当模式为 EXACTLY 或者 AT_MOST 时,尺寸设置为传入的 MeasureSpec 的大小。...
注意,由于View的默认坐标系原点在左上角,因此在调用`draw()`方法前,可能需要对Canvas做一些平移操作,以确保View的绘制位置正确。 以下是一个简单的示例代码: ```java // 创建Bitmap Bitmap bitmap = Bitmap....
基类View的`onMeasure()`默认行为是根据MeasureSpec的模式和尺寸设定自身的大小。`MeasureSpec`类提供了获取模式和尺寸的静态方法。 完成测量后,接下来是布局阶段。 DecorView会调用每个View的`layout(int l, int ...
例如,`CustomViewGroup`可能需要在`onMeasure()`中根据子View的特性来决定布局策略,在`onLayout()`中设置子View的坐标,而在`onDraw()`中可能不进行任何绘制,因为这部分工作通常由子View完成。 除了这些基本步骤...
这个过程由`onMeasure()`方法控制,其中开发者需要指定View的宽度和高度。测量规则遵循MeasureSpec对象,它提供了父视图对子视图尺寸的要求。 3. **布局(Layout)阶段**:在确定了自己的尺寸后,View需要定位自身在...
1. `VISIBLE`:默认状态,View可见且占用布局空间。当一个View被设置为`VISIBLE`时,它不仅会在屏幕上显示,而且会参与布局计算,影响其他View的位置。 2. `INVISIBLE`:View不可见,但仍然占用布局空间。尽管用户...
它们可能重写`onMeasure()`和`onLayout()`方法来确定子View的位置和大小。`ViewDemo`中可能包含一个自定义网格布局的示例,使得可以更灵活地排列子View。 4. 功能型自定义View:这类自定义View通常是为了实现特定的...
同时,利用硬件加速(硬件加速默认开启,但某些操作可能不支持)和View的复用策略(例如,使用ViewStub来延迟加载)也能提升性能。 此外,为了方便其他开发者使用我们的自定义控件,我们应该提供详细的文档说明,...
在`onMeasure()`中,每个View会根据其LayoutParams和父View的要求确定自己的大小;`onLayout()`则根据测量结果确定View的位置;最后,`onDraw()`执行实际的绘制操作,使用Canvas对象来在屏幕上画出内容。 三、...
在Android的默认库中,虽然提供了许多内置的View组件,如Button、TextView、ImageView等,但这些组件可能无法满足所有复杂设计和交互的需求。因此,开发者通常需要自定义View来实现独特的视觉效果、动画或交互逻辑。...
自定义`View`通常包括继承`View`或其子类,然后重写必要的方法和属性,比如`onDraw()`、`onMeasure()`(用于确定View的尺寸)等。 5. **ViewGroup**:`ViewGroup`是`View`的子类,用于组织和管理多个`View`,如线性...
1. **满足特殊需求**:系统默认的View可能无法完全符合设计师的设计理念或应用的特定功能需求。 2. **优化性能**:通过自定义View,可以针对特定场景优化绘制过程,提高应用的运行效率。 3. **代码复用**:自定义...
自定义View允许开发者根据需求扩展系统默认的视图组件,或者构建完全原创的交互元素。本教程将深入探讨Android自定义View的源码实现过程,旨在帮助开发者理解和掌握这一核心技能。 首先,了解自定义View的基本步骤...
这些方法包括`onMeasure()`,这是设置View大小的关键方法,以及`onDraw()`,这是绘制View内容的地方。 ```java public class RectLayout extends View { private Paint paint; public RectLayout(Context ...
2. **构造函数**:重写构造函数,通常包括默认构造函数和带参数的构造函数,用于在XML布局文件中实例化自定义View。 ```java public MyCustomView(Context context) { super(context); } public MyCustomView...
3. **onMeasure()**:此方法用于确定View的大小。我们需要根据文字和图标的需求计算合适的宽度和高度,然后调用`setMeasuredDimension()`。 4. **startLoading()** 和 **stopLoading()**:这两个方法分别用于启动和...
由于自定义View默认并不包含滚动条,因此我们需要手动进行实现。本文将详细介绍如何在自定义View中添加滚动条,并通过分析`TempScrollViewPro`这个示例来讲解相关步骤。 首先,我们需要了解Android中的滚动机制。在...
首先,我们要理解自定义View的核心是继承Android系统的View或ViewGroup类,并重写其关键方法,如onDraw()、onMeasure()和onLayout()等。这些方法分别负责绘制、测量和布局,它们构成了自定义View的基础架构。 在...
3. **布局设计**:在`onMeasure()`方法中,你需要计算控件的大小,确保所有子View都能正确显示。在`onLayout()`方法中,布置子View的位置。 4. **绘制**:重写`onDraw()`方法,根据需求绘制控件的各个部分。可以...
`invalidate()`可以接受一个Rect参数,用来指定需要重绘的区域,如果不传参数,则默认为整个View。 `invalidate()`的内部实现会调用`postInvalidate()`,如果当前View不在UI线程,`postInvalidate()`会将其加入到...