关于listview 的setOnItemClickListener失效问题

来源:互联网 发布:淘宝怎么写标题 编辑:程序博客网 时间:2024/06/05 03:42

正常情况下,为 listview 设置的 setOnItemClickListener 后,当用户点击 listview 的子选项item时就会触发改方法,可是有时候特别的苦恼,明明已经为 listview 设置了监听,可是就点击 listview 的 item 时,却一点响应都没有,接下来我为大家分析一下。

这是有关事件的分发问题,建议先阅读本人的上一篇博客 android事件的分发机制 ,有了这个基础,我们就能更快的了解这其中的道理。

解释:

我们先来看看事件分发机制的结构图(我自己画的,比较丑)


 我们的listview就是图中的view控件,当然图中的view控件中可以有很多个,它们是一层层把事件传递下去的(假如我们在listview里面放入一个button,那么该button也是view控件,它位于listview的下层),ok,要listview不能够被点击有下面两种可是:

1、被处于listview上面的view给拦截了

 故事:我们把图看成公司的职位关系, 当总部分配一件任务下来,首先拿到的是最上层的领导,如果位于员工listview上层的“领导们”觉得这任务得自己干,那么他就不会把任务分配给下属,自己把任务给办了,这时候员工listview就接受不到任务了。

技术:“领导“就是位于listview上层的控件或者容器,他们拦截的方法是重写dispatchTouchEvent()返回true,就代表拦截掉此任务,而任务会在带空间/容器的onTouchEvent()方法被处理,如果处理不了,则交给他上层的空间/容器的onTouchEvent()处理,直到处理完毕

解决方法:检查listview上层的控件/容器是否重写了dispatchTouchEvent()方法,如果有检查方法是否返回true,如果返回true,则要改成false,默认返回super.onInterceptTouchEvent(ev) ,其值是false。

2、事件被listview的下层处理了

故事:部长listview他觉得该任务太简单,就交给下属处理了,下属处理完事件就被消化了,所以部长listView没做任务

技术:一般情况下,如果你没有重写dispatchTouchEvent()时,它默认是返回false(也就是将事件继续往下分发,触发自己是最下面一层了,那就会自己的onTouchEvent()去处理),所以如果你没有重写listview的dispatchTouchEvent()方法时,listview里面又有可focus的控件(比如button,或者不可focus你自己在控件加上android:focusable="true"属性),这时候listview就会把任务分发给下属了,所以你给他任务(点击它),它也不作任何反应。

解决方法:将listview里面的控件改为的android:focusable属性设为false(或者直接把button换成其他不可focus的控件)

3、焦点问题,如果位于listview上层的抢了焦点,那listview就无法获取焦点了。

解决方法:检查listview上层的控件/容器是否设置了android:focusable="true",有的话直接去掉。


这三点基本上已经解决问题了,如果竟然还没解决试试加上下面这个属性

android:descendantFocusability=""

beforeDescendants:viewgroup会优先其子类控件而获取到焦点 
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点 
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点


 谢谢大家


0 0
原创粉丝点击