ListView 中Item点击事件无效的问题
在android开发中,ListView经常需要使用自定义的Item,如果此item中包含如Button、CheckBox等子控件(也可以说是Button或者Checkable的子类控件),则item的点击事件会无效,那该怎么办呢?
网上查了很多资料,回答都是这样的:在子控件上面加上下面几个属性:
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
这个方法,我自己没试过,原因主要是因为要在多个子控件上设置属性,较繁琐,所以想试试有没有更好的解决方式;
幸好,又发现了一种方式,是使用descendantFocusability属性;
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点(这个应该是默认的吧)
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点(说是覆盖,但是自己测试的使用,发现是共存模式,perfect!!)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
>
<ImageView
android:id="@+id/header"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="50dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="36dp"
android:textColor="@color/blue"
/>
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="@color/lightblue"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical|right"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
上面的片段是自己测试用的,设置descendantFocusability=”blocksDescendants”后可以有效区分item的click和button的click事件;
以下是基于自定义BaseAdapter的activity代码:
public class ListviewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
List<ListViewItem> list = getData();
ListViewAdapter adapter = new ListViewAdapter(this, list);
ListView lv = (ListView) findViewById(R.id.listview);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ImageView header = (ImageView) view.findViewById(fmf.ui.R.id.header);
TextView name = (TextView) view.findViewById(fmf.ui.R.id.name);
TextView desc = (TextView) view.findViewById(fmf.ui.R.id.desc);
CheckBox check = (CheckBox) view.findViewById(fmf.ui.R.id.check);
check.setChecked(!check.isChecked());
Toast.makeText(view.getContext(), "click the whole item, item " + name.getText(), Toast.LENGTH_SHORT).show();
}
});
lv.setAdapter(adapter);
}
private List<ListViewItem> getData() {
List<ListViewItem> list = new ArrayList<ListViewItem>();
for (int i = 1; i <= 10; i++) {
ListViewItem item = new ListViewItem();
item.Header = R.drawable.warcraft1;
item.Name = "name" + String.valueOf(i);
item.Desc = "desc" + String.valueOf(i);
item.Check = i % 2 == 1;
list.add(item);
}
return list;
}
}
public class ListViewItem {
public Integer Header;
public String Name;
public String Desc;
public boolean Check;
}
最后是item的布局页和类
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
>
<ImageView
android:id="@+id/header"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="50dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="36dp"
android:textColor="@color/blue"
/>
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="@color/lightblue"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical|right"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
public class Item_ViewHolder {
public ImageView header;
public TextView name;
public TextView desc;
public CheckBox check;
public Button show;
}