Ответ 1
Вы должны установить imageView.setImageDrawable (null)
В onBindViewHolder()
перед установкой изображения с помощью глиссады.
Настройка изображения, которое можно удалить, чтобы устранить проблему.
Надеюсь, что это поможет!
У меня есть адаптер RecyclerView, который выглядит так:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private static Context context;
private List<Message> mDataset;
public RecyclerAdapter(Context context, List<Message> myDataset) {
this.context = context;
this.mDataset = myDataset;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener {
public TextView title;
public LinearLayout placeholder;
public ViewHolder(View view) {
super(view);
view.setOnCreateContextMenuListener(this);
title = (TextView) view.findViewById(R.id.title);
placeholder = (LinearLayout) view.findViewById(R.id.placeholder);
}
}
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false);
ViewHolder vh = new ViewHolder((LinearLayout) view);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message item = mDataset.get(position);
holder.title.setText(item.getTitle());
int numImages = item.getImages().size();
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
}
}
@Override
public int getItemCount() {
return mDataset.size();
}
}
Однако некоторые элементы в RecyclerView показывают изображения, когда их не должно быть. Как я могу остановить это?
Я делаю чек if (numImages > 0) {
в onBindViewHolder()
, но это все еще не останавливает его от показа изображений для элементов, которые не должны иметь изображений.
Вы должны установить imageView.setImageDrawable (null)
В onBindViewHolder()
перед установкой изображения с помощью глиссады.
Настройка изображения, которое можно удалить, чтобы устранить проблему.
Надеюсь, что это поможет!
У меня также были проблемы с RecyclerView, отображающими неправильные изображения. Это происходит потому, что RecyclerView не раздувает представление для каждого нового элемента списка: вместо этого элементы списка перерабатываются.
При просмотре видов обработки мы можем без труда понять представления клонирования. Клонированный вид может иметь изображение, установленное в предыдущем взаимодействии.
Это особенно справедливо, если вы используете Picasso, Glide или какую-либо другую lib для асинхронной загрузки. Эти библиотеки содержат ссылку на ImageView и устанавливают изображение при этом повторении при загрузке изображения.
К моменту загрузки изображения представление элемента может быть клонировано, и изображение будет установлено на неправильный клон.
Короче говоря, я решил эту проблему, ограничив RecyclerView от клонирования представлений моих позиций:
setIsRecyclable(false)
в конструкторе ViewHolder.
Теперь RecyclerView работает немного медленнее, но по крайней мере изображения установлены правильно.
Или загрузите изображение cansel в onViewRecycled(ViewHolder holde)
Проблема в onBindViewHolder, здесь:
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
}
Если numImages равно 0, вы просто разрешаете ранее загруженную загрузку в представление, которое вы повторно используете для продолжения. Когда он закончится, он все равно загрузит старое изображение в ваше представление. Чтобы предотвратить это, скажите Glide, чтобы отменить предыдущую загрузку, вызывая clear:
if (numImages > 0) {
View test = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.images, holder.placeholder, false);
ImageView image = (ImageView) test.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(test);
} else {
Glide.clear(image);
}
Когда вы вызываете into()
, Glide обрабатывает отмену старой загрузки для вас. Если вы не назовете into()
, вы должны позвонить clear()
самостоятельно.
Каждый вызов onBindViewHolder должен включать либо вызов load()
, либо вызов clear()
.
Проблема заключается в том, что, поскольку вы работаете с представлениями, которые будут переработаны, вам нужно будет обрабатывать все возможные сценарии в момент привязки вашего представления.
Например, если вы добавляете ImageView в LinearLayout в позицию 0 источника данных, то, если позиция 4 не удовлетворяет условию, его вид, скорее всего, будет иметь ImageView, добавленный при позиции привязки 0.
Вы можете добавить содержимое содержимого R.layout.images внутри
R.layout.message_layout макет R.id.placeholder и отображение/скрытие заполнителя в зависимости от случая.
Итак, ваш метод onBindViewHolder будет примерно таким:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message item = mDataset.get(position);
holder.title.setText(item.getTitle());
int numImages = item.getImages().size();
if (numImages > 0) {
holder.placeholder.setVisivility(View.VISIBLE);
ImageView image = (ImageView)holder.placeholder.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
}else{
holder.placeholder.setVisibility(View.INVISIBLE);
}
}
У меня была такая же проблема, и я исправил ее так:
ЦЕЛЬ: onViewAttachedToWindow
@Override
public void onViewAttachedToWindow(Holder holder) {
super.onViewAttachedToWindow(holder);
StructAllItems sfi = mArrayList.get(position);
if (!sfi.getPicHayatParking().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicHayatParking() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicSleepRoom().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicSleepRoom() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicSalonPazirayi().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicSalonPazirayi() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
if (!sfi.getPicNamayeStruct().isEmpty()) {
holder.viewFliperMelk.addSlider(new TextSliderView(mContext.getApplicationContext()).image(T.GET_MELK_IMAGE + '/' + sfi.getPicNamayeStruct() + ".jpg").setScaleType(BaseSliderView.ScaleType.CenterCrop));
}
}