自定义带单选框的SimpleCursorAdapter(ListView中增加CheckBox的OnClick响应)
Posted on 2011-05-17 10:24 NCUT蓝色理想 阅读(3125) 评论(0) 编辑 收藏 举报最近在实现一个邮件系统,想仿照Android自带的邮件列表界面,在ListView中显示如下界面
通过Android自带的Hierarchy Viewer分析得知,该ListItem包括:
最左边的View(红色)区分不同的邮箱
左边的复选框ImageView 恩。。不知为啥不用CheckBox实现
中间三个TextView 显示邮件标题 内容及日期
右边的复选框ImageView 星标,也是用ImageView 实现的
恩·· 比较复杂的一个结构,Android对于ListView提供了几种Adapter,不过结构都比较简单、功能也比较少
实现上面的结构还是的自己改进Adapter,首先使用XML构造用于显示ListItem的XML文件
view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget37" android:layout_width="fill_parent"
android:layout_height="64dip" >
<View android:id="@+id/ListBox" android:layout_width="4dip"
android:layout_height="fill_parent" android:background="#ff99ff00" />
<CheckBox android:id="@+id/ListSelected" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_toRightOf="@id/ListBox" android:button="@layout/checkbox" android:checked="false" android:layout_marginLeft="4dip" android:layout_marginTop="1dip" android:focusable="false"/>
<CheckBox android:id="@+id/ListStared" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:button="@layout/starbox" android:checked="false" android:focusable="false"/>
<TextView android:id="@+id/ListSubject" android:layout_width="wrap_content"
android:layout_height="36dip" android:text="Title" android:layout_alignParentTop="true" android:textColor="#ff888888"
android:layout_toLeftOf="@id/ListStared" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_toRightOf="@id/ListSelected" android:gravity="bottom|left"/>
<TextView android:id="@+id/ListFrom" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="mailfrom"
android:layout_alignLeft="@id/ListSubject"
android:layout_below="@id/ListSubject" android:textColor="#ff888888"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView android:id="@+id/ListDate" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="2010/2/0"
android:layout_alignBaseline="@id/ListFrom" android:layout_alignParentRight="true"
android:layout_alignRight="@id/ListStared" android:textColor="#ff888888"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget37" android:layout_width="fill_parent"
android:layout_height="64dip" >
<View android:id="@+id/ListBox" android:layout_width="4dip"
android:layout_height="fill_parent" android:background="#ff99ff00" />
<CheckBox android:id="@+id/ListSelected" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_toRightOf="@id/ListBox" android:button="@layout/checkbox" android:checked="false" android:layout_marginLeft="4dip" android:layout_marginTop="1dip" android:focusable="false"/>
<CheckBox android:id="@+id/ListStared" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:button="@layout/starbox" android:checked="false" android:focusable="false"/>
<TextView android:id="@+id/ListSubject" android:layout_width="wrap_content"
android:layout_height="36dip" android:text="Title" android:layout_alignParentTop="true" android:textColor="#ff888888"
android:layout_toLeftOf="@id/ListStared" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_toRightOf="@id/ListSelected" android:gravity="bottom|left"/>
<TextView android:id="@+id/ListFrom" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="mailfrom"
android:layout_alignLeft="@id/ListSubject"
android:layout_below="@id/ListSubject" android:textColor="#ff888888"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView android:id="@+id/ListDate" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="2010/2/0"
android:layout_alignBaseline="@id/ListFrom" android:layout_alignParentRight="true"
android:layout_alignRight="@id/ListStared" android:textColor="#ff888888"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</RelativeLayout>
xml version="1.0" encoding="utf-8"?>
< RelativeLayout xmlns :android ="http://schemas.android.com/apk/res/android"
android :id ="@+id/widget37" android :layout_width ="fill_parent"
android :layout_height ="64dip" >
< View android :id ="@+id/ListBox" android :layout_width ="4dip"
android :layout_height ="fill_parent" android :background ="#ff99ff00" />
< CheckBox android :id ="@+id/ListSelected" android :layout_width ="wrap_content"
android :layout_height ="wrap_content" android :layout_toRightOf ="@id/ListBox" android :button ="@layout/checkbox" android :checked ="false" android :layout_marginLeft ="4dip" android :layout_marginTop ="1dip" android :focusable ="false" />
< CheckBox android :id ="@+id/ListStared" android :layout_width ="wrap_content"
android :layout_height ="wrap_content"
android :layout_alignParentRight ="true" android :button ="@layout/starbox" android :checked ="false" android :focusable ="false" />
< TextView android :id ="@+id/ListSubject" android :layout_width ="wrap_content"
android :layout_height ="36dip" android :text ="Title" android :layout_alignParentTop ="true" android :textColor ="#ff888888"
android :layout_toLeftOf ="@id/ListStared" android :textAppearance ="?android:attr/textAppearanceLarge"
android :layout_toRightOf ="@id/ListSelected" android :gravity ="bottom|left" />
< TextView android :id ="@+id/ListFrom" android :layout_width ="wrap_content"
android :layout_height ="wrap_content" android :text ="mailfrom"
android :layout_alignLeft ="@id/ListSubject"
android :layout_below ="@id/ListSubject" android :textColor ="#ff888888"
android :textAppearance ="?android:attr/textAppearanceMedium"
/>
< TextView android :id ="@+id/ListDate" android :layout_width ="wrap_content"
android :layout_height ="wrap_content" android :text ="2010/2/0"
android :layout_alignBaseline ="@id/ListFrom" android :layout_alignParentRight ="true"
android :layout_alignRight ="@id/ListStared" android :textColor ="#ff888888"
android :textAppearance ="?android:attr/textAppearanceMedium" />
RelativeLayout >
实现了如下的效果
接下来就是如何编写相应的代码响应各个部分了
1、星标 直接由bool型设定
对于Checkbox,如果直接使用CursorAdapter的方法将boolean型对应到Checkbox上则会显示在Checkbox的Text部分上,而不是对应星标的显示与否。因此我们需要自己实现一个ViewBinder,该方法在转换时遇到Checkbox,则尝试将bool型转换为IsCheck设定。
首先继承一个SimpleCursorAdapter,在初始化时使用setViewBinder,指定我们自己的类型转换函数。
view plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150setViewBinder(new SimpleCursorAdapter.ViewBinder() { public boolean setViewValue(View view, Cursor cursor,int columnIndex) { if (view instanceof CheckBox) { CheckBox v = (CheckBox) view; String src=cursor.getString(columnIndex); if(src.equals("true")){ v.setChecked(true); return true; } else if(src.equals("false")){ v.setChecked(true); return true; } } return false; } }); setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor,int columnIndex) {
if (view instanceof CheckBox) {
CheckBox v = (CheckBox) view;
String src=cursor.getString(columnIndex);
if(src.equals("true")){
v.setChecked(true);
return true;
}
else if(src.equals("false")){
v.setChecked(true);
return true;
}
}
return false;
}
});
首先判断是否是一个Checkbox类型,然后判断能否转换为true或者false,若可以则设置CheckBox的Checked属性。
若不能转换为true或者false则返回false,由Adapter尝试其他方法转换。
在一个ViewBinder里可以增加多个类型判断,之需要满足,转换成功返回true,失败返回false即可,遇到false,Adapter会尝试其他可能转换,如果最终仍未匹配到合适转换,则抛出异常。
2、星标 的事件响应
为了增加星标的事件响应,查找了不少资料,通过几次尝试终于找到了一个合适的设置方法,getView在ListView中负责每个ListItem的结构,修改返回的View增加事件响应即可做到给每个ListItem设定相应的事件。
view plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150public View getView(int position, View convertView,ViewGroup parent) { convertView = super.getView(position, convertView, parent); CheckBox cb= (CheckBox)convertView.findViewById(R.id.ListStared); cb.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Log.v("12", this.toString()); } }); return convertView; } public View getView(int position, View convertView,ViewGroup parent) {
convertView = super.getView(position, convertView, parent);
CheckBox cb= (CheckBox)convertView.findViewById(R.id.ListStared);
cb.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.v("12", this.toString());
}
});
return convertView;
}
由于只需要增加星标的响应,ListItem中的文字显示由父类完成即可,因此先调用了super .getView(position, convertView, parent); 获得显示的View类,然后在该View中查找对应的控件增加事件响应即可。
3、ListItem自身的事件响应
这个就很简单了,对于ListView增加响应即可,唯一需要注意的是,需要先给ListItem中的CheckBox、Button等控件设置Focusable为false,否则会因为CheckBox或者Button占据了ListItem的焦点 而不响应ListItem的点击事件。
基本这样一个类似的结构就可以产生了,接口仍然和原来的SimpleCursorAdapter,增加了几个自己的处理方式,基本实现类似自带邮件的列表效果,不过目前还在考虑每个CheckBox如何和他所在的Position关联在一起,考え中。。。
关于Adapter可以参考下:Adapter的体系http://hi.baidu.com/studymemo/blog/item/d9c3c518a7907972dbb4bd40.html
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wangkemiao/archive/2010/05/19/5609268.aspx