打开一个activity,中setContentView()
-->getWindow().setContentView()
-->getWiendow()返回window,window是抽象类,它的唯一实现PhoneWinodw()
-->phoneWindow()中setContentView(),主要两个方法
|-->installDecor(),创建decorView,创建基础布局
|--为null,geneateDecor()创建DecorView(继承与FramLayout,是容器)对象
|--generateLayout(),根据不同主题确认一个布局id,然后添加进decorView,并获取mContentView(显示容器 中)然后 返回
|-->mLayoutInflater.inflate(layoutResId, mContentParent),将资源加载进布局mContentParent中
---------------------------------------------------------------------------
详细说明加载的过程
------------------------------------------------------------------------
UI绘制相关
View = 模式 + 尺寸->MeasureSpec 32位int值
00000000000000000000000000000000
MODE_MASK : 11000000000000000000000000000000
~MODE_MASK: 00111111111111111111111111111111
SpecMode(前2位) + SpecSize(后30)
public static final int UNSPECIFIED = 0 << MODE_SHIFT; 00000000000000000000000000000000
父容器不对View做任何限制,系统内部使用
public static final int EXACTLY = 1 << MODE_SHIFT; 01000000000000000000000000000000
父容器检测出View的大小,Vew的大小就是SpecSize LayoutPamras match_parent 固定大小
public static final int AT_MOST = 2 << MODE_SHIFT; 10000000000000000000000000000000
父容器指定一个可用大小,View的大小不能超过这个值,LayoutPamras wrap_content
mode + size --> MeasureSpec
MeasureSpec = mode + size
ViewGroup measure --> onMeasure(测量子控件的宽高)--> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)
View measure --> onMeasure --> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)
自定位view时,若mode为AT_MOST时:
需要重写区分:match_parent wrap_content
ViewGroup layout(来确定自己的位置,4个点的位置) -->onLayout(进行子View的布局)
View layout(来确定自己的位置,4个点的位置)
ViewGroup
绘制背景 drawBackground(canvas)
绘制自己onDraw(canvas)
绘制子View dispatchDraw(canvas)
绘制前景,滚动条等装饰onDrawForeground(canvas)
View
绘制背景 drawBackground(canvas)
绘制自己onDraw(canvas)
绘制前景,滚动条等装饰onDrawForeground(canvas)
-----------------------------------------------------------------
onMeasure --> onLayout(容器需要重写) --> onDraw(可选)