ListView – перемещение изображений во время прокрутки

У меня есть ListView с двумя TextViews и одним ImageView. Изображения загружаются из Интернета и кэшируются LruCache. При прокрутке списка ListView изображения перетасовываются на несколько секунд. Для этого не должно быть никакого изображения, пока не будет полностью загружено правильное изображение. Я нашел несколько вопросов с одной и той же проблемой, но никто мне не помог: /. Вот мой код:

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

Было бы хорошо, если бы у кого-то была идея … Спасибо заранее!

PS: Я что-то забыл, пожалуйста, не предлагайте никаких библиотек, я хочу сделать это без какой-либо внешней библиотеки.

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

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

Возможно, этот код

  ViewHolder viewHolder = new ViewHolder(); 

Это каждый раз, когда getView называется новым экземпляром viewHolder.

Попробуйте это вместо этого:

  final ViewHolder viewHolder; 

А затем в if-структуре

  viewHolder = new ViewHolder(); 

Реализовано в вашем коде:

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