ListView – Imágenes barajadas al desplazarse

Tengo un ListView con dos TextViews y un ImageView. Las imágenes se cargan desde Internet y son almacenadas en caché por LruCache. Mientras se desplaza por el ListView, las imágenes se barajan durante unos segundos. Ther simplemente no debe ser ninguna imagen hasta que la imagen correcta está completamente cargada. Encontré algunas preguntas con el mismo problema pero nadie me ayudó: /. Aquí está mi código:

public class NewsAdapter extends BaseAdapter { private static LayoutInflater inflater; private List<Item> items = new LinkedList<Item>(); private LruCache<String, Bitmap> mMemoryCache; public NewsAdapter(Context context) { inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // Bitmap Cache final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return getSizeInBytes(bitmap) / 1024; } }; } public void add(Item item) { items.add(item); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = new ViewHolder(); if(convertView == null) { convertView = inflater.inflate(R.layout.list_item_item, null); viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic); viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } final Item item = items.get(position); viewHolder.tvTitle.setText(item.getTitle()); viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc())); Bitmap bitmap = mMemoryCache.get(item.getPicUrl()); if (bitmap != null) { viewHolder.ivPic.setImageBitmap(bitmap); } else { GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic); gb.execute(); } return convertView; } static class ViewHolder { ImageView ivPic; TextView tvTitle; TextView tvShortDesc; } @Override public int getCount() { return items.size(); } @Override public Item getItem(int position) { return items.get(position); } @Override public long getItemId(int position) { return 0; } @SuppressLint("NewApi") public static int getSizeInBytes(Bitmap bitmap) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { return bitmap.getByteCount(); } else { return bitmap.getRowBytes() * bitmap.getHeight(); } } private class GetBitmap extends AsyncTask<Void, Bitmap, Bitmap> { private String url; private ImageView ivPic; public GetBitmap(String url, ImageView ivPic) { this.url = url; this.ivPic = ivPic; } @Override protected Bitmap doInBackground(Void... params) { Bitmap bitmap = null; try { URL url = new URL(this.url); bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream()); } catch (Exception e) { e.printStackTrace(); } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); if (bitmap != null) ivPic.setImageBitmap(bitmap); } } } 

Sería bueno si alguien tiene una idea … Gracias de antemano!

PS: He olvidado algo, por favor no sugiera ninguna biblioteca, quiero hacerlo sin ninguna biblioteca externa.

 public GetBitmap(String url, ImageView ivPic, int position) { this.url = url; this.ivPic = ivPic; this.position = position; ivPic.setTag(position); ivPic.setImageBitmap(null); } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); if(bitmap != null && ((Integer)getTag) == this.position) ivPic.setImageBitmap(bitmap); } 

El problema es que no está comprobando si la imagen está en la misma posición o no. Prueba el código anterior espero que ayude.

Podría ser este código

  ViewHolder viewHolder = new ViewHolder(); 

Eso es cada vez que getView se llama una nueva instancia de viewHolder es creado.

Prueba esto en su lugar:

  final ViewHolder viewHolder; 

Y luego en la estructura if

  viewHolder = new ViewHolder(); 

Implementado en su código:

  @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder viewHolder; if(convertView == null) { convertView = inflater.inflate(R.layout.list_item_item, null); viewHolder = new ViewHolder(); viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic); viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } final Item item = items.get(position); viewHolder.tvTitle.setText(item.getTitle()); viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc())); Bitmap bitmap = mMemoryCache.get(item.getPicUrl()); if (bitmap != null) { viewHolder.ivPic.setImageBitmap(bitmap); } else { GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic); gb.execute(); } return convertView; } 
  • Un montón de recolección de basura en un listview
  • ListView ya no reacciona a onclick después de una llamada a setSelection ()
  • Android ListView alpha scroller para desplazamiento rápido de larga lista
  • ListView con barra de progreso en cada elemento?
  • Custom ListView con cabecera con pin, causando Jank al ajustar el relleno
  • Cómo mostrar un texto "Cargando ..." mientras recupera elementos para un ListView
  • Archivos no eliminados al borrar y aún mostrados en Listview
  • ListView dinámico en la aplicación para Android
  • Listview no actualizar en fragmento con las pestañas viewpager
  • Cómo dibujar un encabezado de sección en android listview al igual que el UITableview del ios?
  • Los datos del adaptador RecycleView aparecen erróneos al desplazarse demasiado rápido
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.