曾经不知道多少次处理了ListView点击事件传递,每次都会写上focusable=true,简直成了习惯,但一直都处于习惯,没去深究到底为什么?正好现在能深入处理那些问题,也开始深思问题的本身。
首先,focusable是设置焦点,但焦点到底是啥?跟clickable有什么关系?它有什么影响?
好的,进入正题,假如现在写个demo,就是一个竖直的线性布局,里面有一个Edittext、button,然后我们通过电脑的方向键盘,按上按下,这时候我们可以看到Edittext会出现边框,这就是所谓的焦点,也就是告诉我们当前光标或者键盘操作指引的位置。但是,你可能会奇怪,为什么Edittext有,而button没有。这就牵涉到了两组代码。
1、setFocusableInTouchMode(true) requestFocusableFromTouch
2、setFocusable(true) requestFocusable
这两组代码很多时候不会像这个样子分类的,很多都是一股脑全部复制上,其实这也无可厚非,毕竟能解决问题就是王道。但既然这篇文章是分析,就不能这么浅显。
首先,我要告诉大家最简单的差异,第一组代码是给很多原本在触摸屏不能获取焦点事件的View添加焦点事件获取特性(Android默认的Edittext是可以自动获取焦点的,像button那些都是默认没有焦点的,不信可以尝试用第二组代码去设置,看是否会出现获取焦点的情况,可以根据键盘移动到button上对比效果)
其次。在网上会有很多资料告诉你,前面那一项是用于触摸屏幕,下面一组代码是用于键盘(也就是非触摸操作的焦点),这是一个很好的解释。但我在实践的时候使用了第一组代码,然后加上第二组的setFocusable(false),把他们都加在button上。按照上述言论,那么我触摸之后会一直出现效果,通过电脑键盘移动到就不会出现效果,但是结果却让人匪夷所思,竟然没有获取焦点的效果(就是通过键盘移动到那个Button上那种蓝色边框的效果)。
不得已,去看了源码,恍然大悟,虽然说前面的解释没有什么不对,但是对于android的源码,setFocusableInTouchMode和setFocusable、requestFocusableFromTouch和requestFosuabe的相似程度很高,而且setFocusableInTouchMode只是在setFocusable前给View做了一个判断,如果能自动获取焦点就继续,不然就让顶层类获取焦点,让它能获取焦点。同样的,在requestFocusableFromTouch的时候也是惊人的相似,同样是先对View本身的判断,然后判断顶层类是否能添加。但是,最大的亮点是他们基于同样的方法,同样的类,如果你再给同样的View设置两组效果,很明显他们会共用同样的数据,所以若想用这两组代码实现各种相逆效果,有点不妥,因为他们的基于的同样的数据,如果一个方法改变了数据,那自然会改变前一个方法带来的改变效果。所以,不能实现相逆效果