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!
- OnItemClickListener en un ListView dentro de un fragmento no funciona
- Cómo cambiar el color y la fuente en ListView
- Cómo guardar y restaurar la posición de ListView en Android
- Android: colocar anuncio en la parte inferior de la pantalla
- Android: el evento onItemClick () de ListView no se llama
PS: He olvidado algo, por favor no sugiera ninguna biblioteca, quiero hacerlo sin ninguna biblioteca externa.
- Agrupar filas similares en listview en función de su contenido
- ¿Cómo agregar un listview dentro de un viewpager?
- TouchDelegate aplicado a ListView sólo responde al evento de clic
- Las extensiones de vínculo se pierden de la conversión de ListView
- Menú de tipo ListView anidado de forma arbitraria de Android
- Android, SlidingPaneLayout y listView
- Configuración del elemento ListView marcado desde Adapter
- Establecer la altura de la fila ListView en el código
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; }
- No puede compilar la aplicación de Android con el reino
- Cómo mantener un archivo jar externo, pero todavía uso de sus clases en mi proyecto de Android?