我正在实现一个支持多项选择的图片库。主要布局是 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 方法时会发生什么:
- 最初选中的复选框未选中
- 选中一组新的 N 个复选框
这种行为让我想到 gridview 项目可能出乎意料地改变了它们在 GridView
中的位置,所以我为每个项目添加了一个具有唯一名称的 TextView
.我的想法是正确的:当我滚动屏幕时,项目会改变它们在 GridView
中的位置。调用 uncheckAll 时也会发生同样的情况。我找到了适合我的解决方案 in this thread .
注意:一开始我没有意识到移动问题,因为在这个开发阶段我为每个 GridView
项目使用相同的 ImageView
资源。
最佳答案
问题很可能是您的 getView() 方法正确地初始化了一个新的单元格 View ,但从未更新已回收的单元格 View 的状态。所以基本上每个单元格 View 只会显示它被初始化的状态。它应该看起来像这样:
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 .
关于android - 具有自定义 ImageAdapter 的 GridView 在数据集更改后不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11832907/