导航

最近在实现一个邮件系统,想仿照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