I have a custom ListView
Adapter
, with which I'm creating rows for a list. My problem is though, that it doesn't seem to be distinguishing the ImageView
s, from each other. It seems to be randomly picking ImageViews
to chuck into place as I scroll up and down. The text information (omitted from this snippet) does not break. It works as one would expect.
Here is the relevant method of my Adapter
:
public View getView( int position, View convertView, ViewGroup parent )
{
View v = convertView;
if( v == null )
{
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate( R.layout.generic_row, null );
}
// find the image
ImageView favImage = (ImageView)v.findViewById( R.id.toggle_favorite );
// when clicked...
favImage.setOnClickListener( new OnClickListener() {
@Override
public void onClick( View v )
{
// make the gray star a yellow one
int newImage = R.drawable.ic_star_yellow_embossed;
((ImageView)v).setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(), newImage));
}
});
return v;
}
you need to define the default image right after finding its reference:
you need to do this because once the image is changed, and you scroll the ListView , it reappears because ListView recycles the item views. So you need to define it in getView to use a default image when the list is scrolled
That behavior appears because the
ListView
recycles the row views as you scroll the list up and down, and because of this you get rows that were acted on by the user(the image was changed) in position were the image should be unmodified. To avoid this you'll have to somehow hold the status of theImageView
for every row in the list and use this status to set up the correct image in thegetView()
method. Because you didn't say how exactly did you implement your adapter I will show you a simple example.First of all you should store your the statuses of the
ImageView
. I used anArrayList<Boolean>
as a member of the custom adapter, if the position(corresponding to the row's position in the list) in this list isfalse
then the image is the default one, otherwise if it istrue
then the user clicked it and we should put the new image:In your custom adapter constructor initialize this list. For example if you put in your adapter a list of something then you should make your
imageStatus
as big as that list and filled withfalse
(the default/start status):Then in your
getView()
method:This should work well if you don't plan to dynamically modify the list(remove/add rows), otherwise you'll have to take care of also modifying that list of
imageStatus
to reflect the changes. You didn't say what was your row data, another approach(and the right one if you plan to do something if the user clicks that image(besides changing it)) is to incorporate the status of the image in the row's data model. Regarding this here are some tutorials:Android ListView Advanced Interactive or Commonsware-Android Excerpt (Interactive rows)