没有合适的资源?快使用搜索试试~ 我知道了~
首页面试_Android_PDF知识大全.pdf
面试_Android_PDF知识大全.pdf
需积分: 10 121 浏览量
更新于2023-05-27
评论
收藏 25.45MB PDF 举报
Android面试知识点大全, 包含Android基础知识, 数据库 ,网络, 算法等等。对面试者会有很大的帮助。
资源详情
资源评论
资源推荐

2019 年百度 Android 面试题-公共技术点
之 View 绘制流程
View
绘制机制
1. View 树的绘图流程【文末有彩蛋】
当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android
framework 处理.绘制是从根节点开始,对布局树进行 measure 和 draw。整个
View 树的绘图流程在 ViewRoot.java 类的 performTraversals()函数展开,该函数
所做 的工作可简单概况为是否需要重新计算视图大小(measure)、是否需要重新
安置视图的位置(layout)、以及是否需要重绘(draw),流程图如下:
View 绘制流程函数调用链

需要说明的是,
用户主动调用 request,只会出发 measure 和 layout 过程,而不会执行 draw
过程
2. 概念
measure 和 layout
从整体上来看 Measure 和 Layout 两个步骤的执行:

树的遍历是有序的,由父视图到子视图,每一个 ViewGroup 负责测绘它所有的
子视图,而最底层的 View 会负责测绘自身。
具体分析
measure 过程由 measure(int, int)方法发起,从上到下有序的测量 View,在
measure 过程的最后,每个视图存储了自己的尺寸大小和测量规格。 layout 过
程由 layout(int, int, int, int)方法发起,也是自上而下进行遍历。在该过程中,每
个父视图会根据 measure 过程得到的尺寸来摆放自己的子视图。
measure 过程会为一个 View 及所有子节点的 mMeasuredWidth 和
mMeasuredHeight 变量赋值,该值可以通过 getMeasuredWidth()和
getMeasuredHeight()方法获得。而且这两个值必须在父视图约束范围之内,这
样才可以保证所有的父视图都接收所有子视图的测量。如果子视图对于
Measure 得到的大小不满意的时候,父视图会介入并设置测量规则进行第二次
measure。比如,父视图可以先根据未给定的 dimension 去测量每一个子视图,
如果最终子视图的未约束尺寸太大或者太小的时候,父视图就会使用一个确切的
大小再次对子视图进行 measure。
measure 过程传递尺寸的两个类

1.ViewGroup.LayoutParams (View 自身的布局参数)
2.MeasureSpecs 类(父视图对子视图的测量要求)
ViewGroup.LayoutParams
这个类我们很常见,就是用来指定视图的高度和宽度等参数。对于每个视图的
height 和 width,你有以下选择:
1.具体值
2.MATCH_PARENT 表示子视图希望和父视图一样大(不包含 padding 值)
3.WRAP_CONTENT 表示视图为正好能包裹其内容大小(包含 padding 值)
ViewGroup 的子类有其对应的 ViewGroup.LayoutParams 的子类。比如
RelativeLayout 拥有的 ViewGroup.LayoutParams 的子类
RelativeLayoutParams。
有时我们需要使用 view.getLayoutParams() 方法获取一个视图 LayoutParams,
然后进行强转,但由于不知道其具体类型,可能会导致强转错误。其实该方法得
到的就是其所在父视图类型的 LayoutParams,比如 View 的父控件为
RelativeLayout,那么得到的 LayoutParams 类型就为 RelativeLayoutParams。
MeasureSpecs
测量规格,包含测量要求和尺寸的信息,有三种模式:
1.UNSPECIFIED
父视图不对子视图有任何约束,它可以达到所期望的任意尺寸。比如 ListView、
ScrollView,一般自定义 View 中用不到,

2.EXACTLY
父视图为子视图指定一个确切的尺寸,而且无论子视图期望多大,它都必须在该
指定大小的边界内,对应的属性为 match_parent 或具体值,比如 100dp,父
控件可以通过 MeasureSpec.getSize(measureSpec)直接得到子控件的尺寸。
3.AT_MOST
父视图为子视图指定一个最大尺寸。子视图必须确保它自己所有子视图可以适应
在该尺寸范围内,对应的属性为 wrap_content,这种模式下,父控件无法确定
子 View 的尺寸,只能由子控件自己根据需求去计算自己的尺寸,这种模式就是
我们自定义视图需要实现测量逻辑的情况。
3. measure 核心方法
measure(int widthMeasureSpec, int heightMeasureSpec)
该方法定义在 View.java 类中,为 final 类型,不可被复写,但 measure 调用
链最终会回调 View/ViewGroup 对象的 onMeasure()方法,因此自定义视图时,
只需要复写 onMeasure() 方法即可。
onMeasure(int widthMeasureSpec, int heightMeasureSpec)
该方法就是我们自定义视图中实现测量逻辑的方法,该方法的参数是父视图对子
视图的 width 和 height 的测量要求。在我们自身的自定义视图中,要做的就
是根据该 widthMeasureSpec 和 heightMeasureSpec 计算视图的 width 和
height,不同的模式处理方式不同。
setMeasuredDimension()
测量阶段终极方法,在 onMeasure(int widthMeasureSpec, int
heightMeasureSpec) 方法中调用,将计算得到的尺寸,传递给该方法,测量阶
剩余937页未读,继续阅读











安全验证
文档复制为VIP权益,开通VIP直接复制

评论0