(一)Android View的加载源码分析
view是如果被加载到界面上的?
创建一个普通的activity
1 |
|
PhoneWindow.java文件
1 |
|
1 |
|
1 |
|
View就这样被加载到界面上了
总结:
* 创建顶层布局容器DecorView
* 在顶层布局中添加基础布局ViewGroup
* 将contentView添加到基础布局容器的FrameLayout中
(二) Android View绘制源码分析
view是如何绘制的?
- ActivityThread.class
1 |
|
- 2.handleLaunchActivity
- 3.handleResumeActivity
- 4.wm.addView(decor, l);
1 |
|
view的绘制流程就是以上这些步骤,现在具体来看下performMeasure(),performLayout(),performDraw()这三步关键的步骤。
- 测量:performMeasure()
- 先引入一个概念MeasureSpec,view的测量规格,是一个32位的二进制整数类型。view的测量按照一定的规则,以下是MeasureSpec的一些规则:
1 |
|
- 继续回到 ViewRootImpl 的1890行 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
1 |
|
- int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); //1854 ViewRootImpl.java
1 |
|
总结: viewGroup : measure -> onMeasure(子控件的宽高) -> setMeasuredDimension() -> setMeasuredDimensionRaw(保存自己的宽高)
view : measure -> onMeasure() -> setMeasuredDimension() -> setMeasuredDimensionRaw(保存自己的宽高)
自定义view不重写onMeasure方法,使用match_parent 和 wrap_content的效果是一样的布局performLayout() ,回到performLayout(lp, desiredWindowWidth, desiredWindowHeight); //1931 ViewRootImpl.java
1 |
|
总结:viewGroup: layout(确定自己的位置,4个点的位置)->onLayout(进行子view的布局)
view: layout(确定自己的位置,4个点的位置)performDraw绘制 //2067 ViewRootImpl.java
1 |
|
总结:
viewGroup:
- 绘制背景drawBackground()
- 绘制自己onDraw()
- 绘制子view dispatchDraw()
- 绘制前景,滚动条等装饰onDrawForeground()
view:
- 绘制背景drawBackground()
- 绘制自己onDraw()
- 绘制前景,滚动条等装饰onDrawForeground()