Мои изображения меняются во время прокрутки в списке

На прошлой неделе я просто попытаюсь решить эту проблему. См. Все подобные вопросы, и я не знаю, почему решения для меня не работают. У меня есть список, и каждый элемент имеет представление изображения. При нажатии на изображение, я хочу изменить ресурс изображения. Что ж. все сделано. Но при прокрутке меняются ресурсы изображений. Мой полный код:

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; } 

}

Где я ошибаюсь?

попробуй это,

 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; } } 

Добавить класс модели:

 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; } } 

Вы должны использовать одно логическое значение в держателе, чтобы проверить, установлено ли фоновое изображение или нет для определенной строки.

держатель

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

Установить изображение

 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); } 

Надеюсь, это поможет.

Это связано с тем, что при прокрутке системы Android вида listview всегда создается новая строка и уничтожается невидимые строки. Вам нужно изменить getView (), как показано ниже, и все будет хорошо:

 @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; } 

Вы должны определить layoutInflater в конструкторе, потому что getView () вызывает для каждой строки, поэтому, если вы определяете layoutInflater в getView (), LayoutInflater определяет снова и снова для каждой строки.

Да, эта проблема всегда появляется в ListView потому что андроид всегда уничтожает и воссоздает в ней строки.

У вас есть два варианта:

Во-первых , измените свой адаптер, чтобы сохранить статус для каждой строки в ListView и проверьте этот статус перед отображением строки.

Во-вторых , я рекомендовал этот вариант и использовал его в своем коде, вы можете использовать RecyclerView , эта проблема не будет с ним.

Intereting Posts
API-интерфейс Google Calendar OAuth2 на Android-соте Таблица устаревших Android-карт Приложение Chromecast Sender не обнаруживает разъединение / повторное соединение Вызов члена класса JAVA из Native C / C ++ кода Как можно управлять вариантами вывода с помощью Android Gradle Plugin 3.0.0+? Шифровать данные в Android с помощью файла public.pem RSA, сгенерированного в Ruby Java.lang.IllegalArgumentException: зарегистрировать слишком много широковещательных приемников Как получить возвращаемое значение из AsyncTask в главную активность? Реализация 47degree android-swipelistview для прокрутки android ListViewItem Сообщение Android Toast не показывает Как добавить панели инструментов в AppCompatPreferenceActivity? Синхронизация проекта Android Gradle завершилась неудачно из-за целевой версии Платформа Google для Android – NoClassDefFoundError: com.google.android.gms.samples.plus.SignInActivity Элемент ActionBar не отображается, когда ShapeDrawable установлен как значок Как установить минимальную дату DatePicker на текущую дату