在使用Android Listview时,我们经常需要多选,Android Listview 已经自带了些多选+checkbox样式,但如果要满足个人需求而重新自定义Listview,将要重写ListAdapter。本文通过Contact List来介绍如何满足这一要求--
1. 运行效果:
2. 代码分析:
对于一个ListView来说,关键是ListAdapter的实现。Android ListView 已经自带了一些简单的ItemView和Adapter,如下:
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
lView = (ListView) findViewById(R.id.ListView01);
// Set option as Multiple Choice. So that user can able to select more the one option from list
lView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice, lv_items));
lView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
}
源自http://www.androidpeople.com/android-listview-multiple-choice-example
注意这幅图中并没有下面一行Email显示,所以要想按照自己的方式显示List,就必须自定义 --
- 定义itemview,形如:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<RelativeLayout android:id="@+id/contactinfo_layout" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_alignParentLeft="true" >
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" android:gravity="center_vertical"
style="@style/TextAppearance.LineMajorFont_Label" android:id="@+id/fullnameText" />
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content"
style="@style/TextAppearance.LineMinorFont_Label" android:layout_below="@id/fullnameText"
android:singleLine="true" android:id="@+id/detailText" />
</RelativeLayout>
<CheckBox android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/checkBox" android:layout_alignParentRight="true" android:layout_marginRight="5dp"/>
</RelativeLayout>
- 定义要显示的数据结构,这里类取名叫Item
public String nameText = null;
public String detailText = null;
public boolean ischecked = false;
}
- 定义将要显示的控件绑定在一起,类取名叫ItemViewCache
public TextView nameText = null;
public TextView detailText = null;
public CheckBox checkbox = null;
}
- 定义ItemAdapter
private Context mContext = null;
public ItemAdapter(Context context, int textViewResourceId, List<Item> objects) {
super(context, textViewResourceId,objects);
mContext = context;
}
/*
* (non-Javadoc)
*
* @see android.widget.ArrayAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.itemofcontactlist, null);
final ItemViewCache cache = new ItemViewCache();
cache.nameText = (TextView) convertView
.findViewById(R.id.fullnameText);
cache.detailText = (TextView) convertView
.findViewById(R.id.detailText);
cache.checkbox = (CheckBox)convertView.findViewById(R.id.checkBox);
cache.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
Item it = (Item)cache.checkbox.getTag();
it.ischecked=cache.checkbox.isChecked();
}
});
convertView.setTag(cache);
cache.checkbox.setTag(this.getItem(position));
}else {
((ItemViewCache)convertView.getTag()).checkbox.setTag(this.getItem(position));
}
ItemViewCache theCache = (ItemViewCache) convertView.getTag();
if(this.getItem(position)!= null) {
theCache.nameText.setText(this.getItem(position).nameText);
theCache.detailText.setText(this.getItem(position).detailText);
theCache.checkbox.setChecked(this.getItem(position).ischecked);
}
// theCache.placeicon.setImageResource(R.id.placeicon);
return convertView;
}
}
这里的关键是getView中,对checkbox的OnCheckedChange事件的响应,如红色字体。
- 数据载入,即准备List<Item> objects, 这个比较简单--
private List<Item> populateList(ContentResolver cr){
List<Item> items = new ArrayList<Item>();
//Cursor cur = ContactListView.this.managedQuery(Email.CONTENT_URI, projection, null, null, null);
Cursor emailCur = cr.query( Email.CONTENT_URI, projection, null, null, null);
while (emailCur.moveToNext()) {
// This would allow you get several email addresses
// if the email addresses were stored in an array
Item item = new Item();
String email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
item.detailText=email;
String name = emailCur.getString(
emailCur.getColumnIndex(Contacts.DISPLAY_NAME));
item.nameText=name;
items.add(item);
}
emailCur.close();
return items;
}
3. 参考:
http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/
http://www.higherpass.com/Android/Tutorials/Accessing-Data-With-Android-Cursors/2/