Phil Phil - 4 months ago 50
Java Question

Android Imageview in Listview onClick change image doesn't work properly

I have a ListView and in every single ListviewItem there is an ImageView with a little star (for marking it as favourite). Therefore I put an OnClickListener to the ImageView on every item in the custom ArrayAdapter.

imgStar.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bitmap bitmap = ((BitmapDrawable)imgStar.getDrawable()).getBitmap();
Bitmap bitmap2 = ((BitmapDrawable)(context.getResources().getDrawable(R.drawable.ic_action_not_important))).getBitmap();

if(bitmap != bitmap2) {
imgStar.setImageResource(R.drawable.ic_action_not_important);
} else {
imgStar.setImageResource(R.drawable.ic_action_important);
}
}
});


The problem: When I get some items and click for example on the star of the first item, the image changes as it should but a few items lower the image changes too o.O
I tested it with some code: The thing that won't get into my head is it is only changing the image (on the other item below), code that would be executed in the onclick is only executed for the item I really click not for the one where the image changes too.

Why does the image of a random other item in the list change also? I hope someone can help me.

Custom Adapter Constructore Code

public LinkArrayAdapter(Context con, int textViewResourceId) {
super(con, textViewResourceId);
context = con;

}

Answer

The main problem is that you can't change the image of items in the onClick then leave it and hope it will be updated on every item on the list. Because onClick get called in different time than getView. So you must set item images outside of onClick but in the getView so every time that getView called for a specific item it will set the appropriate image for that item.

Define a boolean array in your CustomAdapter class as:

private boolean[] stars;

Then in constructor method of your class, initialize it as:

this.stars = new boolean[items.size()];

In the onClick method:

// **Edited to apply image update at click**
stars[position] = !stars[position];
notifyDataSetInvalidated();

At last in the getView() method of custom adapter (ensure this code is not in any other inner blocks):

if (stars[position])
  imgStar.setImageResource(R.drawable.ic_action_important);
else
  imgStar.setImageResource(R.drawable.ic_action_not_important);