自定义View入门——NO.2

自定义View入门——NO.2

自定义View的View绘制流程

ActivityThread类中
关键代码
关键代码
关键代码
ActivityClientRecord不为null,经一系列判断,调用 wm.addView(decor, l);
关键代码
将decorView加载到WindowManager
关键代码
Window类中创建WindowManager
关键代码
跳转到WindowManagerImpl,View的绘制流程才开始。
关键代码
其调用的是WindowManagerImpl中的addView(),
关键代码
再在其中调用WindowManagerGlobal的addView()
关键代码
ViewRootImpl是最外层布局,DecorView嵌套其中。
再在其中调用ViewRootImpl的setView()
关键代码
再在其中调用requestLayout()
关键代码
再在其中调用scheduleTraversals()
关键代码
再在其中调用mTraversalRunnable
关键代码
再在其中调用doTraversal()
关键代码
再在其中调用performTraversals()

关键代码
关键代码
关键代码
接下来的源码要根据xml中的布局来查看,以LinearLayout为例
关键代码

关键代码
关键代码
关键代码
测量模式和大小是由父布局和自己决定的。
关键代码
关键代码
此时,都会调用setMeasuredDimension(); 这个时候我们布局才真正指定宽度measuredWidth和高度measuredHeight。

接着执行ViewGroup的onMeasure(),指定自己的宽高(需要不断叠加子View的高度,marign,padding)。

View绘制流程measure方法总结
第一步performMeasure():用于指定和测量布局中所有控件的宽高。对于ViewGroup,先去测量子控件,根据子控件的宽高来计算和指定自己的宽高;对于View,它的宽高是由自己和父布局决定的。
第二步performLayout():用于摆放子布局或控件。通过for循环所有子View,调用childLayout()。
关键代码
关键代码
关键代码
以LinearLayout为例
关键代码
关键代码
关键代码
第三步performDraw():绘制所有View。对于ViewGroup,首先绘制自己的背景,然后通过for循环绘制子View的draw()方法;对于View,绘制自己的背景,绘制自己显示的内容(文字,图片,背景等)。
关键代码
关键代码
关键代码
关键代码
画背景
关键代码
画自己 画子View 不断循环调用子View的draw()
关键代码

该源码使用了模板设计模式。
思考问题:
1.如果想要获取View的高度,前提肯定需要调用测量方法,测量完毕后才能获取宽高。
2.View的绘制流程是在onResume()之后才开始(Activity启动流程源码)。
3.addView,setVisibility等等会调用requestLayout(),重走View绘制流程。
4.优化的时候,要根据源码来优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值