-
View 只支持Padding,不支持Margin, ViewGroup 支持Margin
-
View 负责draw自己和handle event, 而Android Framework负责measuring, layout.
-
View ID need not be unique throughout the tree, but it is good practice to ensure that they are at least unique within the part of the tree you are searching.
-
LayoutInflator 负责从XML文件生成对应的View tree.
-
AttributeSet 代表view的属性,View的属性分为两种,一种是普通属性,另一种是layout parameters,这种属性以layout开头,用来布局。
View的属性可以在XML中设置,也可以在代码中设置。
View支持的属性需要定义一个declare-styleable资源,这在定义Custom View时是必须的。
-
View的绘制过程
-
生成View tree
通过LayoutInflator从XML文件中生成View tree, 此阶段从XML中提取出树型结构来构造View tree.从每个XML TAG中提取出各View Node的属性。
此时,各View的大小还没定下来,只是定个了各种属性,其中layout属性用在下一阶段测量View的大小上。
-
遍历View tree,求得各Node View的大小。
此阶段称为Measure阶段,主要是确定各View的Measured大小,其主要利用的是父View所指定的测量Spec和子View的LayoutParameter属性。所以说,View的Measured大小是由其父View和子View共同决定的。
以上大小只是测量的大小,实际大小要在Layout阶段确定,一般测量大小就是实际的大小。
主要函数:
onMeasure():如果需要更改测量行为,需要覆盖该方法
-
再一次遍历View tree,求得各Node View的布局位置
此阶段是用来确定各Node View的最终摆放位置。
主要函数:
onLayout():如果需要更改布局行为,需要覆盖该方法
-
再一次遍历View tree. 将各Node View绘制出来。
这是最后一个阶段,确定了大小和位置后就可以绘制View了。
主要函数:
onDraw():如果需要更改绘制行为,需要覆盖该方法
-
三个遍历的起点都在ViewRoot的
performTraversal
方法中
-
-
View 重新绘制
当某一个View的状态更改时,如Button的压下状态,此时,需要对该View进行重新绘制。
第一步是从该View起,不断向上找其父View,并对其进行标记是否需要重绘。直到RootView.
RootView会向一个MESSAGE-QUEUE发送一个DO_TRAVERSAL消息,并在handleMessage()中接收该消息,当收到该消息后,会再走一遍performTraversal对View Tree进行遍历,但这一次View中并没有要求重新测量标志位,所以并不进行measuer pass和layout pass.
由上可知,View中存在一些标志位来决定是否对其进行measure,layout和draw.
-
invalite() 调用它后,onDraw会在将来的某一时间被调用
-
requestLayout() 调用该函数会 schedule a layout pass of the view tree.
网友评论