①、performLayout :View -> layout() -> onLayout()

②、摆放子布局 for循环所有子View, 前提不是GONE,调用child.layout()

③、performDraw() : View -> draw() -> drawBackground();//画背景
onDraw(canvas);// 画自己 ViewGroup 默认情况下不会调用
dispatchDraw(canvas);// 画子View 不断的循环调用子View的 draw()

面试 [ View的绘制流程]

第一步 performMeasure():用于指定和测量layout中所有控件的宽高,对于ViewGroup,先去测量里面的子孩子,根据子孩子的宽高再来计算和指定自己的宽高,对于View,它的宽高是由自己和父布局决定的。

第二步 performLayout(): 用于摆放子布局,for循环所有子View,用child.layout()摆放ChildView

第三步 performDraw(): 用于绘制自己还有子View , 对于ViewGroup首先绘制自己的背景,for循环绘制子View调用子View的draw()方法, 对于View绘制自己的背景,绘制自己显示的内容(TextView)

思考问题:

  • 如果要获取View的高度,前提肯定需要调用测量方法,测量完毕之后才能获取宽高

  • View的绘制流程是在 onResume() 之后才开始(Activity 启动流程的源码)

  • addView setVisibility 等等 会调用requestLayout(); 重新走一遍View的绘制流程

  • 优化的时候,根据知道源码写代码的时候优化, onDraw() 不要布局嵌套,等等

1.流式布局:我之前写过二篇文章:http://blog.csdn.net/qq_24675479/article/details/78921070,动态添加流式布局http://blog.csdn.net/qq_24675479/article/details/78928339这里不阐述了

2.自定义View和ViewGroup套路总结

2.1 自定义View的套路:

    2.1.1 自定义属性,获取自定义属性(达到配置的效果) 
    2.1.2 onMeasure()方法用于测量计算自己的宽高,前提是继承自View,如果是继承自系统已有的 TextView , Button ,已经给你计算好了宽高
    2.1.3 onDraw() 用于绘制自己的显示 
    2.1.4 onTouch() 用于与用户交互

2.2 自定义ViewGroup的套路:

    2.2.1 自定义属性,获取自定义属性(达到配置的效果)很少有

    2.2.2 onMeasure() 方法,for循环测量子View,根据子View的宽高来计算自己的宽高

    2.2.3 onDraw() 一般不需要,默认情况下是不会调用,如果你要绘制需要实现dispatchDraw()方法

    2.2.4 onLayout() 用来摆放子View,前提是不是GONE的情况

    2.2.5 在很多情况下不会继承自ViewGroup ,往往是继承 系统已经提供好的ViewGroup 如 ViewPager ScrollView  RelativeLayout
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐