第5章 View相关面试问题
1、View绘制面试问题讲解
a) view树的绘制流程
measure---->layout------>draw
整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为:
根据之前设置的状态,判断是否需要重新计算视图大小(measure)、是否重新需要安置视图的位置(layout)、以及是否需要重绘(draw),其框架过程如下:
b) measure
从上往下进行有序的遍历
MeasureSpec
SpecMode的三种模式
1.EXACTLY:当我们将控件的“layout_width”属性或者“layout_height”属性指定为具体数值时,比如“android:layout_width="200dp"”,或者指定为“match_parent”时,系统会使用这个模式
2.AT_MOST:当控件的“layout_width”属性或者“layout_height”属性设置为“wrap_content”时,控件大小一般会随着内容的大小而变化,但是无论多大,也不能超过父控件的尺寸
3.UNSPECIFIED:表示开发人员可以将视图按照自己的意愿设置成任意的大小,没有任何限制。这种情况比较少见,一般在绘制自定义View的时候才会用到。
measure-重要方法
measure()-----> onMeasure()----->setMeasuredDimension()
c) layout
d) draw
invalidate()
requestLayout()
invalidate系列方法请求重绘View树(也就是draw方法),如果View大小没有发生变化就不会调用layout过程,并且哪个View请求invalidate系列方法,就绘制该View。
2、事件分发面试问题讲解
a) 为什么会有事件分发机制
安卓上面的view是树形结构的,view可能会重叠在一起,当我们点击的地方有多个view都可以响应的时候,这个点击事件应该给谁呢?为了解决这一个问题,就有了事件分发机制。
https://www.jianshu.com/p/e42b638944ae
b) 三个重要的事件分发方法
方法 | 作用 | 调用时刻 |
dispatchTouchEvent | 分发(传递)点击事件 | 当点击事件能够传递给当前View时,该方法就会被调用 |
onInterceptTouchEvent | 判断是否拦截了某个事件(Activity和View中没有该函数,只存在于ViewGroup中) | 在ViewGroup中的dispatchTouchEvent内部调用 |
onTouchEvent | 处理点击事件 | 在dispatchTouchEvent内部调用 |
c) 事件分发流程
Activity-->PhoneWindow-->DecorView-->ViewGroup-->View
3、ListView缓存问题面试讲解
a) 什么是listView
listview就是一个能将数据集合以动态滚动的方式展示到用户界面的view
b) listview适配器模式
c) listview的RecycleBin机制
ListView的父类AbsListView中的内部类RecycleBin(防止ListView出现oom)
setViewTypeCount()(不同布局的个数)
d) listview的优化
1. getview中的convertView中起到缓存作用,有缓存就不创建
2.ViewHolder作用,减少多次findViewByID的次数
3.少做耗时操作,一定要做的话就要监听listview滑动事件,停止滑动的时候再去做
4.减少半透明的绘制,因为半透明的绘制比较耗时