本文参考了讨论区:http://stackoverflow.com/questions/9900913/onitemclicklistener-was-not-work-with-the-checkbox
1. 适配TextView(最常见情况)
第一种情况,TextView的布局是match_parent,那么ListView每一项中整个Item区域都是TextView。分两种情况:
² 如果TextView进行了监听设置(下面黄色区域代码),那么ListView的OnItemClickListener无响应,因为点击事件被操作系统直接分派给了TextView,也就是说,TextView的监听会优先处理事件,处理完毕后不再扩散该点击事件。
² 如果TextView没有进行监听设置,那么ListView的OnItemClickListener会响应。
public class MyAdapter3extendsBaseAdapter{
private Context context;
MyAdapter3(Context context){
this.context=context;
}
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(intposition) {
return null;
}
@Override
public long getItemId(intposition) {
return 0;
}
@Override
public View getView(final intposition,View convertView,ViewGroup parent) {
View view=convertView;
Holder holder;
if (view==null){
view= LayoutInflater.from(context).inflate(R.layout.item_layout3,parent,false);
holder=new Holder();
holder.textView=(TextView)view.findViewById(R.id.textview);
view.setTag(holder);
}else {
holder=(Holder)view.getTag();
}
holder.textView.setOnClickListener(newView.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,"测试:OnClickListener"+position,Toast.LENGTH_SHORT).show();
}
});
return view;
}
private static class Holder{
TextView textView;
}
}
第二种情况,TextView的布局是wrap_context,ListView的布局为match_parent,那么ListView每一项中整个Item区域一部分是TextView,一部分是ListView的空白区域。分两种情况:
² 如果TextView进行了监听设置(下面黄色区域代码),那么如果点击空白区域,ListView的OnItemClickListener有响应,点击TextView区域,响应TextView的监听。
² 如果TextView没有进行监听设置,那么ListView的OnItemClickListener在空白区域和TextView处都会响应。
2.适配Button及其子类
这包括了ImageButton、CheckedBox等Button子类,如果这些组件是wrap_context,ListView的布局为match_parent,即每一项Item有空白区域。
² 第一种情况,如果这些组件都没有设置监听(注意,对于CheckedBox即便不设置监听,其实组件本身也已经有监听了,用于改变它的选中状况),点击空白区域ListView的OnItemClickListener会有响应,点击组件区域,不会响应。
² 第二种情况,如果这些组件都设置监听(注意,对于CheckedBox即便不设置监听,其实组件本身也已经有监听了,用于改变它的选中状况),点击空白区域ListView的OnItemClickListener不会有响应,点击组件区域,响应组件监听的事件。不同于TextView,一旦这些组件有监听,不管点击空白区域还是组件区域,操作系统都会将点击事件分配给这些组件,这些组件不会将点击事件再扩散出来。
注意,CheckedBox一定是有监听的。对于第二种情况,如果需要让组件有监听,同时点击空白区域能响应OnItemClickListener,那需要让组件不优先获得焦点,有两种方法
1)布局时组件设置为不可获得焦点,即黄色部分。也可在代码中设置。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:focusableInTouchMode="false" android:text="测试" /> </LinearLayout>
2)布局时组件的父容器设置阻止子组件获得焦点,即黄色部分。也可在代码中设置。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" android:orientation="vertical"> <CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试"/> </LinearLayout>
其中,android:descendantFocusability的API解释如下:
Defines the relationshipbetween the ViewGroup and its descendants when looking for a View to takefocus.
Must beone of the following constant values.
3.总结
本文解释了这种现象:如果ListView适配CheckBox这类Checkable组件时,即便不设置监听,也不能在响应OnItemClickListener是一件非常奇怪的事情。