I'm implementing a gallery of images with support for multiple item selection. The main layout is a GridView
which uses a custom Adapter
. Every displayed item is a combination ImageView
+ CheckBox
. If several checkboxes are checked I want to uncheck them all simply by touching any image in the GridView
. I'm calling notifyDataSetChanged()
for implementing this functionality. Unfortunately this "uncheck all" feature doesn't work. I'm still a newbie so probably there is something basic that I don't understand. Could somebody tell me what is wrong with my Adapter
? Thanks.
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();
}
}
Update
I've realised that my initial post doesn't describe exactly how the uncheckAll method fails. What happens when I have N checked checkboxes and call the uncheckAll method is:
- the initially checked checkboxes are unchecked
- a new group of N checkboxes are checked
This behavior made me to think that maybe the gridview items were, unexpectedly, changing their positions in the GridView
so I added a TextView
with a unique name to every item. My thought was correct: when I scrolled the screen the items change their position in the GridView
. The same happens when uncheckAll is called. I've found a solution working for me in this thread.
Note: I didn't realise about the moving problem at the very beginning because at this stage of development I was using the same ImageView
resource for every GridView
item.