版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】AndroidView绘制机制的详解
View绘制机制一、View树的绘图流程当Activity接收到焦点的时候,它会被请求绘制布局,该请求由Androidframework处理.绘制是从根节点开始,对布局树进行measure和draw。整个View树的绘图流程在ViewRoot.java类的performTraversals()函数展开,该函数所做的工作可简单概况为是否需要重新计算视图大小(measure)、是否需要重新安置视图的位置(layout)、以及是否需要重绘(draw),流程图如下:
View绘制流程函数调用链
需要说明的是,用户主动调用request,只会出发measure和layout过程,而不会执行draw过程二、概念1.measure和layout从整体上来看Measure和Layout两个步骤的执行:树的遍历是有序的,由父视图到子视图,每一个ViewGroup负责测绘它所有的子视图,而最底层的View会负责测绘自身。2.具体分析
measure过程由measure(int,int)方法发起,从上到下有序的测量View,在measure过程的最后,每个视图存储了自己的尺寸大小和测量规格。
layout过程由layout(int,int,int,int)方法发起,也是自上而下进行遍历。在该过程中,每个父视图会根据measure过程得到的尺寸来摆放自己的子视图。measure过程会为一个View及所有子节点的mMeasuredWidth和mMeasuredHeight变量赋值,该值可以通过getMeasuredWidth()和getMeasuredHeight()方法获得。而且这两个值必须在父视图约束范围之内,这样才可以保证所有的父视图都接收所有子视图的测量。如果子视图对于Measure得到的大小不满意的时候,父视图会介入并设置测量规则进行第二次measure。比如,父视图可以先根据未给定的dimension去测量每一个子视图,如果最终子视图的未约束尺寸太大或者太小的时候,父视图就会使用一个确切的大小再次对子视图进行measure。3.measure过程传递尺寸的两个类ViewGroup.LayoutParams
这个类我们很常见,就是用来指定视图的高度和宽度等参数。对于每个视图的height和width,你有以下选择:ViewGroup的子类有其对应的ViewGroup.LayoutParams的子类。比如RelativeLayout拥有的ViewGroup.LayoutParams的子类RelativeLayoutParams。
有时我们需要使用view.getLayoutParams()方法获取一个视图LayoutParams,然后进行强转,但由于不知道其具体类型,可能会导致强转错误。其实该方法得到的就是其所在父视图类型的LayoutParams,比如View的父控件为RelativeLayout,那么得到的LayoutParams类型就为RelativeLayoutParams。MeasureSpecs
测量规格,包含测量要求和尺寸的信息,有三种模式:UNSPECIFIED
父视图不对子视图有任何约束,它可以达到所期望的任意尺寸。比如ListView、ScrollView,一般自定义View中用不到,EXACTLY
父视图为子视图指定一个确切的尺寸,而且无论子视图期望多大,它都必须在该指定大小的边界内,对应的属性为match_parent或具体值,比如100dp,父控件可以通过MeasureSpec.getSize(measureSpec)直接得到子控件的尺寸。AT_MOST
父视图为子视图指定一个最大尺寸。子视图必须确保它自己所有子视图可以适应在该尺寸范围内,对应的属性为wrap_content,这种模式下,父控件无法确定子View的尺寸,只能由子控件自己根据需求去计算自己的尺寸,这种模式就是我们自定义视图需要实现测量逻辑的情况。3、measure核心方法measure(intwidthMeasureSpec,intheightMeasureSpec)
该方法定义在View.java类中,为final类型,不可被复写,但measure调用链最终会回调View/ViewGroup对象的onMeasure()方法,因此自定义视图时,只需要复写onMeasure()方法即可。onMeasure(intwidthMeasureSpec,intheightMeasureSpec)
该方法就是我们自定义视图中实现测量逻辑的方法,该方法的参数是父视图对子视图的width和height的测量要求。在我们自身的自定义视图中,要做的就是根据该widthMeasureSpec和heightMeasureSpec计算视图的width和height,不同的模式处理方式不同。setMeasuredDimension()
测量阶段终极方法,在onMeasure(intwidthMeasureSpec,intheightMeasureSpec)方法中调用,将计算得到的尺寸,传递给该方法,测量阶段即结束。该方法也是必须要调用的方法,否则会报异常。在我们在自定义视图的时候,不需要关心系统复杂的Measure过程的,只需调用setMeasuredDimension()设置根据MeasureSpec计算得到的尺寸即可,你可以参考ViewPagerIndicator的onMeasure方法。下面我们取ViewGroup的measureChildren(intwidthMeasureSpec,intheightMeasureSpec)方法对复合View的Measure流程做一个分析:
MeasureChild的方法调用流程图:
源码分析4、layout相关概念及核心方法首先要明确的是,子视图的具体位置都是相对于父视图而言的。View的onLayout方法为空实现,而ViewGroup的onLayout为abstract的,因此,如果自定义的View要继承ViewGroup时,必须实现onLayout函数。在layout过程中,子视图会调用getMeasuredWidth()和getMeasuredHeight()方法获取到measure过程得到的mMeasuredWidth和mMeasuredHeight,作为自己的width和height。然后调用每一个子视图的layout(l,t,r,b)函数,来确定每个子视图在父视图中的位置。LinearLayout的onLayout源码分析5、绘制流程相关概念及核心方法先来看下与draw过程相关的函数:View.draw(Canvascanvas):
由于ViewGroup并没有复写此方法,因此,所有的视图最终都是调用View的draw方法进行绘制的。在自定义的视图中,也不应该复写该方法,而是复写onDraw(Canvas)方法进行绘制,如果自定义的视图确实要复写该方法,那么请先调用super.draw(canvas)完成系统的绘制,然后再进行自定义的绘制。View.onDraw():
View的onDraw(Canvas)默认是空实现,自定义绘制过程需要复写的方法,绘制自身的内容。dispatchDraw()
发起对子视图的绘制。View中默认是空实现,ViewGroup复写了dispatchDraw()来对其子视图进行绘制。该方法我们不用去管,自定义的ViewGroup不应该对dispatchDraw()进行复写。绘制流程图
View.draw(Canvas)源码分析由上面的处理过程,我们也可以得出一些优化的小技巧:当不需要绘制Layer的时候第二步和第五步会跳过。因此在绘制的时候,能省的layer尽可省,可以提高绘制效率ViewGroup.dispatchDraw()源码分析drawChild(canvas,this,drawingTime)
直接调用了View的child.draw(canvas,this,drawingTime)方法,文档中也说明了,除了被ViewGroup.drawChild()方法外,你不应该在其它任何地方去复写或调用该方法,它属于ViewGroup。而View.draw(Canvas)方法是我们自定义控件中可以复写的方法,具体可以参考上述对view.draw(Canvas)的说明。从参数中可以看到,child.draw(canvas,this,drawingTime)肯定是处理了和父视图相关的逻辑,但View的最终绘制,还是View.draw(Canvas)方法。invalidate()
请求重绘View树,即draw过程,假如
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 金融科技在消费金融中的安全保障措施研究
- 大健康产业运营及营销推广策略研究
- 公司产品专员招聘要点分析
- 企业技术转化中的创新思路与方法探讨
- 旅游行业导游员岗位面试技巧指导
- 教育装备公司业务销售经理招聘策略全解析
- 劳动保障医保就业前景
- 制造业总经理面试常见问题
- 法规事务部业务培训计划及执行情况反馈
- 物流公司经理面试全解析
- 水库工程蓄水安全鉴定报告
- 《化工安全技术》教学设计(教学教案)
- 无神论宣讲少先队活动
- 项目五 汽车液压传动系统
- 四年级下册科学全册知识点归纳
- 降低消化内镜故障发生率
- 婚内债务夫妻方承担协议书
- 整厂物品设备回收合同
- 统一战线基本理论方针政策课件
- 大一美术学解刨透视知识点
- 盘扣式脚手架专项施工方案
评论
0/150
提交评论