Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Adaptador RecyclerView que muestra imágenes incorrectas

Tengo un adaptador de RecyclerView que se parece a esto:

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

Sin embargo, algunos de los elementos de RecyclerView muestran imágenes cuando no deberían estarlo. ¿Cómo puedo evitar que esto suceda?

Hago el cheque if (numImages > 0) { en onBindViewHolder() , pero eso todavía no lo detiene de mostrar imágenes para los artículos que no deben tener imágenes.

  • Diferencia entre android: id, android: nombre y nombre de las etiquetas en los archivos XML de Android
  • Android: El editor XML predeterminado ya no se abre
  • ¿Vista de lista con título, imagen y texto?
  • ¿Por qué el elemento Fragmento en el diseño de Android está escrito con una letra minúscula 'f'?
  • En Android XML, ¿puedo establecer buttonStyleSmall o Button.Small como un estilo padre para un estilo personalizado?
  • ¿Cuál es la diferencia entre TypedArray.getInteger () y TypedArray.getInt ()?
  • Android: cómo agregar a los niños de un diseño xml en una vista personalizada
  • Relacionar URI con <data> como http://example.com/algo en AndroidManifest
  • 4 Solutions collect form web for “Adaptador RecyclerView que muestra imágenes incorrectas”

    También tuve problemas con RecyclerView mostrando imágenes incorrectas. Esto sucede porque RecyclerView no está inflando la vista para cada nuevo elemento de la lista: en su lugar los elementos de la lista se están reciclando.

    Al reciclar las visiones podemos entender mal las opiniones de clonación . Una vista clonada puede tener un conjunto de imágenes de la interacción anterior.

    Esto es especialmente justo si está usando Picasso, Glide, o alguna otra lib para la carga asíncrona. Estas bibliotecas contienen referencia a un ImageView y establecen una imagen en esa referencia cuando se carga la imagen.

    En el momento en que la imagen se carga, la vista del elemento podría haberse clonado, y la imagen se va a establecer en el clon equivocado .

    Para hacer una larga historia corta, he resuelto este problema mediante la restricción de RecyclerView de la clonación de puntos de vista de mi artículo:

    setIsRecyclable(false) en el constructor de ViewHolder.

    Ahora RecyclerView está funcionando un poco más lento, pero al menos las imágenes se ajustan a la derecha.

    O también puede cargar la imagen en onViewRecycled(ViewHolder holde)

    Debe establecer imageView.setImageDrawable (null) In onBindViewHolder() antes de configurar la imagen con glide.

    Ajustar la imagen dibujable a null soluciona el problema.

    ¡Espero eso ayude!

    El problema está en onBindViewHolder, aquí:

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

    Si numImages es igual a 0, simplemente está permitiendo que la carga iniciada previamente en la vista que está reutilizando continúe. Cuando termine, seguirá cargando la imagen antigua en su vista. Para evitar esto, dígale a Glide que cancele la carga anterior llamando a 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); } 

    Cuando llama into() , Glide se encarga de cancelar la carga antigua para usted. Si no va a llamar into() , debe llamar a clear() usted mismo.

    Cada llamada a onBindViewHolder debe incluir una llamada load() o una llamada clear() .

    El problema aquí es que, como usted está trabajando con las vistas que van a ser reciclados, tendrá que manejar todos los posibles escenarios en el momento de la vinculación de su punto de vista.

    Por ejemplo, si está agregando el ImageView al LinearLayout en la posición 0 del origen de datos, entonces, si la posición 4 no cumple con la condición, su vista tendrá muy probablemente el ImageView agregado al enlazar la posición 0.

    Puede agregar el contenido del contenido de R.layout.images dentro de su

    R.layout.message_layout Layout de R.id.place y mostrar / ocultar el marcador de posición dependiendo del caso.

    Por lo tanto, su método onBindViewHolder sería algo como:

     @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); } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.