网上大部分的这类例子都是事先定好了item数量,无法实时增加item并得到check状态,
还有一个问题,要考虑到 CheckBox 的状态保持。比如程序开始运行后,在屏幕上显示 ListView 中的第 0~ 第5 个条目,第 6 、 7 两个条目在屏幕上不可见,这时候,我们点击第 0 个条目的 CheckBox ,那么这个 CheckBox 就会被显示为 Checked 的状态,然后我们将整个 ListView 向下滚动到底,那么第 0 个条目就不可见了。如果我们再将整个 ListView 向上滚动到头,那么此时第 0 个条目又可见了,如果不做一些处理,我们将会发现,第 0 个条目对应的 CheckBox 本应该处于 Checked 状态,但在它重新出现时,居然自动变成了 unChecked 的状态。
这个代码可以很好解决这两个问题
gallery_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gallery_item_layout"
android:layout_width="140px"
android:layout_height="140px"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:background="@drawable/gallery_item" >
<TextView
android:id="@+id/gallery_item_text"
android:layout_width="fill_parent"
android:layout_height="70px"
android:textSize="20px"
android:gravity="center"
android:paddingLeft="10px"
android:paddingRight="20px"
android:textColor="#ffffffff"/>
<!-- android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
如果想让 ListView 中的item可以接收 click 事件,那么需要将
上面三个属性,加入到 CheckBox 对象的属性中即可
这三句很重要,由于checkbox的点击事件优先级比listview的高,所以要在checkbox中添加android:focusable="false",使得checkbox初始的时候没有获取焦点。 -->
<CheckBox
android:id="@+id/gallery_item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="80px"
android:visibility="invisible"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>
</LinearLayout>
MyGalleryAdapter:
public class MyGalleryAdapter extends SimpleAdapter{
private boolean checkBoxShow = false;
ArrayList<Boolean> checkList = new ArrayList<Boolean>();
public MyGalleryAdapter(Context context, List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
// TODO Auto-generated constructor stub
}
public ArrayList<Boolean> getCheckList(){
return checkList;
}
/**
* 建立一个记录每个item的checkbox状态的list,然后刷新每个item。
* @param itemlist
*/
public void notifyDataSetChanged(ArrayList<HashMap<String, Object>> itemlist) {
// TODO Auto-generated method stub
checkList.clear();
for(int i=0; i<itemlist.size(); i++){
checkList.add(false);
}
super.notifyDataSetChanged();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return super.getCount();
}
/**
* 设置显示checkBox
* @param show false 不显示,true 显示
*/
public void setCheckBoxShow(boolean show){
checkBoxShow = show;
notifyDataSetChanged();
}
/**
* 返回checkBox是否显示的状态
* @return true 显示, false 不显示
*/
public boolean getCheckBoxShowState(){
return checkBoxShow;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
TextView nameText;
CheckBox checkBox;
LinearLayout programListLayout;
View v;
// TODO Auto-generated method stub
v=super.getView(position, convertView, parent);
programListLayout = (LinearLayout)v.findViewById(R.id.gallery_item_layout);
nameText = (TextView)v.findViewById(R.id.gallery_item_text);
checkBox = (CheckBox)v.findViewById(R.id.gallery_item_checkbox);
if(checkBoxShow){
checkBox.setVisibility(View.VISIBLE);
checkBox.setChecked(checkList.get(position));//根据list里的记录显示checkbox状态
}
else
checkBox.setVisibility(View.INVISIBLE);
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//改变list里相应的item的checkbox记录状态
if(checkList.get(position))
checkList.set(position, false);
else
checkList.set(position, true);
}
});
return v;
}
}
Activity中的代码:
adapter = new MyGalleryAdapter(this, list, R.layout.gallery_item, new String[]{Constant.KEY_NAME,"KeyCheckBox"}, new int[]{R.id.gallery_item_text,R.id.gallery_item_checkbox});
searchGallery.setAdapter(adapter);
获取选中的checkBox的idx
ArrayList<Boolean> myCheckedList = adapter.getCheckList();
if(myCheckedList.size()!=0){
for(int i=0; i<myCheckedList.size(); i++){
if(myCheckedList.get(i) == true){
Log.i(TAG, "idx:"+i);
}
}
隐藏checkBox
adapter.setCheckBoxShow(false);
如果实时增加item后,需要调用
adapter.notifyDataSetChanged(list);
来增加Adapter中的ArrayList记录,同时刷新ListView或者Gallery的显示
在使用ListView和Gallery的时候,要注意因为 ListView 可以在垂直方向滚动,那么总有一些条目是在屏幕上看不到的,这些看不到的条目,如果你试图用 ListView.GetChildAt(intposition) 去获取它时,你会发现得到的结果将会是 null 。