我实施了一个支持多项选择的图片库。主要布局为GridView
,使用自定义Adapter
。每个显示的项目都是ImageView
+ CheckBox
的组合。如果选中了多个复选框,我只想通过触摸GridView
中的任何图像取消选中它们。我正在调用notifyDataSetChanged()
来实现此功能。不幸的是,这"取消选中所有"功能不起作用。我还是个新手,所以可能有一些基本的东西我不明白。有人能告诉我Adapter
有什么问题吗?感谢。
public class ImageAdapter extends BaseAdapter {
private Context mContext;
// References to our images
public Integer[] mThumbIds = {
R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3
};
// The layout inflater used to retrieve gallery children layouts
private LayoutInflater mInflater;
// Array used to update checkboxes
public boolean[] checkboxesState = new boolean[getCount()];
public ImageAdapter(Context c) {
mContext = c;
mInflater = (LayoutInflater)
c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Define the initial checked/unchecked state of the checkboxes
for(int i = 0; i < getCount(); i++) {
checkboxesState[i] = false;
}
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/* Create a new View for each cell displayed in the GridView.
* In our case a View is an instance of RelativeLayout from which
* we can extract the image and checkbox to be displayed in the cell
*/
public View getView(int position, View convertView, ViewGroup parent) {
View cell = convertView;
if (cell == null) {
// No View passed, create one.
cell = mInflater.inflate(R.layout.galleryitem, null);
// Setup the View content
ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage);
CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox);
checkBox.setChecked(checkboxesState[position]);
checkBox.setId(position);
imageView.setImageBitmap(downsample(mThumbIds[position]));
// Setup the View behavior
imageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Uncheck all checked items
uncheckAll();
}
});
checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
checkboxesState[cb.getId()] = cb.isChecked();
}
});
}
return cell;
}
private Bitmap downsample(int resId){
// Some code here
}
private void uncheckAll() {
// This code does not work. GridView is not refreshed
for(int i = 0; i < checkboxesState.length; i++) {
checkboxesState[i] = false;
}
notifyDataSetChanged();
}
}
更新
我已经意识到我的初始帖子并没有准确描述uncheckAll方法的失败方式。当我检查N复选框并调用uncheckAll方法时会发生什么:
这种行为让我觉得gridview项目可能意外地改变了他们在GridView
中的位置,所以我为每个项目添加了一个唯一名称的TextView
。我的想法是正确的:当我滚动屏幕时,项目会更改GridView
中的位置。调用uncheckAll时也会发生同样的情况。我找到了一个适合我的解决方案in this thread。
注意:我一开始并没有意识到移动问题,因为在这个开发阶段,我为每个ImageView
项使用了相同的GridView
资源。
答案 0 :(得分:1)
问题很可能是你的getView()方法正确地初始化了一个新的单元格视图,但从未更新已被回收的单元格视图的状态。所以基本上每个单元格视图只会显示它初始化的状态。看起来应该是这样的:
public View getView(int position, View convertView, ViewGroup parent) {
View cell = convertView;
if (cell == null) {
// No View passed, create one.
cell = mInflater.inflate(R.layout.galleryitem, null);
// Setup the View content
ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage);
CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox);
checkBox.setChecked(checkboxesState[position]);
checkBox.setId(position);
imageView.setImageBitmap(downsample(mThumbIds[position]));
// Setup the View behavior
imageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Uncheck all checked items
uncheckAll();
}
});
checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
checkboxesState[cb.getId()] = cb.isChecked();
}
});
} else {
ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage);
CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox);
checkBox.setChecked(checkboxesState[position]);
checkBox.setId(position);
imageView.setImageBitmap(downsample(mThumbIds[position]));
}
return cell;
}
此外,为了提高getView()方法的性能,请查看此tutorial。