My images change while scrolling through the list

Last week I will just try to solve this problem. see all similar questions and I donโ€™t know why the solutions do not work for me. I have a list and each item has an image view. when I click on the image, I want to change the resource of the image. Well. done. but when scrolling, image resources change. my full code is:

public class CustomBaseAdapter extends BaseAdapter { Context context; ArrayList<String> items; public CustomBaseAdapter(Context context,ArrayList<String> items){ this.context = context; this.items = items; } private class ViewHolder{ TextView titr; ImageView image; } @Override public int getCount() { return items.size(); } @Override public Object getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return items.hashCode(); } @Override public View getView(int position, View view, ViewGroup parent) { View vi = view; final ViewHolder holder ; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if(view==null){ vi = inflater.inflate(R.layout.customlistitem,null); holder = new ViewHolder(); holder.titr = (TextView) vi.findViewById(R.id.listtext); holder.image = (ImageView) vi.findViewById(R.id.listimg); holder.image.setTag(position); vi.setTag(holder); } else{ holder = (ViewHolder) vi.getTag(); } holder.titr.setText(items.get(position)); holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { v.setBackgroundResource(R.drawable.fav_ic); } }); return vi; } 

}

where am i wrong

+6
source share
5 answers

try it,

 public class CustomBaseAdapter extends BaseAdapter { Context context; ArrayList<Items> items; public CustomBaseAdapter(Context context,ArrayList<Items> items){ this.context = context; this.items = items; } private class ViewHolder{ TextView titr; ImageView image; } @Override public int getCount() { return items.size(); } @Override public Items getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return items.hashCode(); } @Override public View getView(int position, View view, ViewGroup parent) { View vi = view; final ViewHolder holder ; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if(view==null){ vi = inflater.inflate(R.layout.customlistitem,null); holder = new ViewHolder(); holder.titr = (TextView) vi.findViewById(R.id.listtext); holder.image = (ImageView) vi.findViewById(R.id.listimg); holder.image.setTag(position); vi.setTag(holder); } else{ holder = (ViewHolder) vi.getTag(); } holder.titr.setText(items.get(position).getStrTxt()); holder.image.setImageResource(items.get(position).getDrawableImage()); holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { items.set(position,new Items(R.drawable.fav_ic)); notifyDataSetChanged(); } }); return vi; } } 

Add model class:

 public class Items { int drawableImage; String strTxt; public Items(int drawableImage) { this.drawableImage = drawableImage; } public int getDrawableImage() { return drawableImage; } public void setDrawableImage(int drawableImage) { this.drawableImage = drawableImage; } public String getStrTxt() { return strTxt; } public void setStrTxt(String strTxt) { this.strTxt = strTxt; } } 
+1
source

you need to use one boolean value in the holder to check if the background image is set or not for a specific line.

Holder

 private class ViewHolder{ TextView titr; ImageView image; boolean isSet; } 

set image

 holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { v.setBackgroundResource(R.drawable.fav_ic); holder.isSet = true } }); if(holder.isSet) { holder.image.setBackgroundResource(R.drawable.fav_ic); } else{ holder.image.setBackgroundResource(no image or other image); } 

hope this helps.

+6
source

This is because when you scroll through the Android system of the listview view, always create a new line and destroy invisible lines. You need to change getView () as shown below and everything will be fine:

 @Override public View getView(int position, View view, ViewGroup parent) { View vi = view; final ViewHolder holder ; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); if(view==null){ vi = inflater.inflate(R.layout.customlistitem,null); holder = new ViewHolder(); holder.titr = (TextView) vi.findViewById(R.id.listtext); holder.image = (ImageView) vi.findViewById(R.id.listimg); holder.image.setTag(position); vi.setTag(holder); } else{ holder = (ViewHolder) vi.getTag(); } holder.titr.setText(items.get(position)); if(sp.getBoolean("position="+position, false)){ v.setBackgroundResource(R.drawable.fav_ic); } holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { v.setBackgroundResource(R.drawable.fav_ic); SharedPreferences.Editor edit = sp.edit(); edit.putBoolean("position="+position, true); edit.commit(); } }); return vi; } 
+1
source

You have to define layoutInflater in the constructor, because getView () calls for each row, so if you define layoutInflater in getView (), LayoutInflater defines again and again for each row.

+1
source

Yes, this problem always appears in the ListView , because the android always destroys and recreates the rows in it.

You have two options:

At first . Change your adapter to keep the status for each row in the ListView , and check this status before displaying the row.

Second , I recommended this option and used it in my code, you can use RecyclerView , this problem will not be with it.

+1
source

All Articles