首页 > 代码库 > Android ListView不响应OnItemClickListener解决办法

Android ListView不响应OnItemClickListener解决办法

 

有时候,当ListView中的每一个item是自定义的View时,有可能会导致ListView的OnItemClickListener的listener无法调用,请看如下情况:

如果你的自定义ListViewItem中有Button或者Checkable的子类控件的话,那么默认focus是交给了子控件,而 ListView的Item能被选中的基础是它能获取Focus,也就是说我们可以通过将ListView中Item中包含的所有控件的 focusable属性设置为false,这样的话ListView的Item自动获得了Focus的权限,也就可以被选中了。

我们可以通过对Item Layout的根控件设置其android:descendantFocusability="blocksDescendants"即可,这样Item Layout就屏蔽了所有子控件获取Focus的权限,不需要针对Item Layout中的每一个控件重新设置focusable属性了,如此就可以顺利的响应onItemClickListener中的onItemClick()方法了。

总结: 

原因:

ListView中的Item内部的View获得了焦点,如Button, Checkbox等。 

解决办法: 

不要让ListView中的Item内部的View获得焦点就OK了,这样做:android:descendantFocusability="blocksDescendants"

public static final int descendantFocusability

Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.

 

ConstantValueDescription
beforeDescendants0The ViewGroup will get focus before any of its descendants.
afterDescendants1The ViewGroup will get focus only if none of its descendants want it.
blocksDescendants2The ViewGroup will block its descendants from receiving focus.

 

注意:
还有一种情况也会导致OnItemClickListener或OnItemLongClickListener回调不会执行,那就是ListView的child设置了onClickListener或onLongClickListener。我们可以通过源代码看出,在你调用setOnClickListener()方法后,它会调用setClickable(true),在onTouchEvent里面的实现如下: 

[java] view plaincopy
  1. if (((viewFlags & CLICKABLE) == CLICKABLE ||  
  2.                 (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {  
  3.   
  4.     // ....  
  5.   
  6.     return true;  
  7. }  

当一个View在onTouchEvent里面返回true后,ListView就不会正常接收到事件。

Android ListView不响应OnItemClickListener解决办法