View的相关面试题(待补充)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25859403/article/details/52024773

1 常用组件的使用:ListView、RecyclerView及Adapter的使用

2 View之间的继承关系

3 Invalidate与postInvalidate的区别

前者是在UI线程自身中使用,而后者在非UI线程中使用。

怎么说呢?Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 鉴于此,如果要使用invalidate的刷新,那我们就得配合handler的使用,使异步非ui线程转到ui线程中调用,如果要在非ui线程中直接使用就调用postInvalidate方法即可,这样就省去使用handler的烦恼。

4 自定义view的实现方式(根据项目经验询问相关组件)。

5 onMeasure/onLayout/onDraw的作用

http://blog.csdn.net/zhaoweixing1989/article/details/46009889

(1)onMeasure:

onMeasure(int widthMeasureSpec,int heightMeasureSpec)  

1、调用时间:当控件的父元素放置该控件时,用于告诉父元素该控件需要的大小。

2、传入参数:widthMeasureSpec,heightMeasureSpec。这两个传入参数由高32位和低16位组成,高32位保存的值叫specMode,可以通过MeasureSpec.getMode()获取;低16位为specSize可以由MeasureSpec.getSize()获取。这两个值是由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同决定。权值weight也是尤其需要考虑的因素,有它的存在情况可能会稍微复杂点。

specMode可以取三个值:MeasureSpec.EXACTLY ,MeasureSpec.AT_MOST,MeasureSpec.UNSPECIFIED;

specMode与layout_的对应关系如下:

match_parent - MeasureSpec.EXACTLY:当layout_为match_parent或者为某一具体值的时候specMode为EXACTLY代表精确的值;

wrap_content - MeasureSpec.AT_MOST:表示能获得的最大尺寸;

当无法确定尺寸的时候则是 MeasureSpec.UNSPECIFIED,这时候specSize会为最小值(即0);

3、可以在onMeasure()中来计算控件的尺寸,然后根据setMeasuredDimension(mWidth,mHeight);方法来告诉父控件此控件需要的尺寸,onMeasure()方法中必须调用此方法。

4、值得注意的是:
1)specSize和传入setMeasuredDimension()方法中的值的单位都是px(dp*density就是px)。
2)match_parent并不是填充整个父容器,而是在不覆盖已经加入父容器的控件的情况下填充父容器.

(2)onLayout:

onLayout(boolean changed, int left, int top,int right,int bottom);

父容器的onLayout()调用子类的onLayout()来确定子view在viewGroup中的位置,如:onLayout(10,10,100,100)表示子容器在父容器中(10,10)位置显示,长、宽都是90。结合onMeasure()方法使用可以确定子view的布局。

(3)onDraw:

 onDraw(Canvas canvas)

自定义view的关键方法,用于绘制界面,可以重写此方法以绘制自定义View。

小结:

    一般来说,在自定义View时,需要重写onMeasure()和onDraw()  
             自定义ViewGroup时需要重写,onMeasure() 和onLayout()

6 Paint、Matrix、Shader等绘制相关类的方法作用

(1)Paint(画笔):

(2)Canvas(画布):

(3)Path(路径):

(4)Matrix(矩阵):

参考: 深入理解 Android 中的 Matrix

(5)Shader(着色器):

参考:Android中Canvas绘图之Shader使用图文详解

7 详细描述事件分发机制

源码解释1:
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
画图解释:图解 Android 事件分发机制

  1. onTouch和onTouchEvent有什么区别,又该如何使用?

从源码中可以看出,这两个方法都是在View的dispatchTouchEvent中调用的,onTouch优先于onTouchEvent执行。如果在onTouch方法中通过返回true将事件消费掉,onTouchEvent将不会再执行。

另外需要注意的是,onTouch能够得到执行需要两个前提条件,第一mOnTouchListener的值不能为空,第二当前点击的控件必须是enable的。因此如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。

  1. 为什么给ListView引入了一个滑动菜单的功能,ListView就不能滚动了?

如果你阅读了Android滑动框架完全解析,教你如何一分钟实现滑动菜单特效 这篇文章,你应该会知道滑动菜单的功能是通过给ListView注册了一个touch事件来实现的。如果你在onTouch方法里处理完了滑动逻辑后返回true,那么ListView本身的滚动事件就被屏蔽了,自然也就无法滑动(原理同前面例子中按钮不能点击),因此解决办法就是在onTouch方法里返回false。

  1. 为什么图片轮播器里的图片使用Button而不用ImageView?

提这个问题的朋友是看过了Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来 这篇文章。当时我在图片轮播器里使用Button,主要就是因为Button是可点击的,而ImageView是不可点击的。如果想要使用ImageView,可以有两种改法。第一,在ImageView的onTouch方法里返回true,这样可以保证ACTION_DOWN之后的其它action都能得到执行,才能实现图片滚动的效果。第二,在布局文件里面给ImageView增加一个android:clickable=”true”的属性,这样ImageView变成可点击的之后,即使在onTouch里返回了false,ACTION_DOWN之后的其它action也是可以得到执行的。

今天的讲解就到这里了,相信大家现在对Android事件分发机制又有了进一步的认识,在后面的文章中我会再带大家一起探究Android中ViewGroup的事件分发机制,感兴趣的朋友请继续阅读 Android事件分发机制完全解析,带你从源码的角度彻底理解(下) 。

猜你喜欢

转载自blog.csdn.net/qq_25859403/article/details/52024773