2012-11-22 86 views
1

我已將我的ListView與圖片放在我的活動中,工作良好,直到添加LRU緩存。當我加載第一次(如果我不滾動它),而圖像加載第一個元素改變它之間的圖像我加載的所有圖像。Lru Cache列表查看圖片問題

我LRU緩存看起來像

public class Image { 
    private static LruCache<String, Bitmap>  mMemoryCache = null; 
    private static int       cacheSize  = 1024 * 1024 * 10; 

    private static class AsyncLoader extends AsyncTask<String, Void, Bitmap> { 
     private ImageView mTarget; 

     public AsyncLoader(ImageView target) { 
      this.mTarget = target; 
     } 

     @Override 
     protected void onPreExecute() { 
      mTarget.setTag(this); 
     } 

     @Override 
     protected Bitmap doInBackground(String...urls) { 
      String url = urls[0]; 

      Bitmap result = null; 

      if (url != null) { 
       result = load(url); 

       if (result != null) { 
        mMemoryCache.put(url, result); 
       } 
      } 

      return result; 
     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      if (mTarget.getTag() == this) { 
       mTarget.setTag(null); 
       if (result != null) mTarget.setImageBitmap(result); 
      } 
     } 
    } 

    public static Bitmap load(String urlString) { 
     if (urlString == null || urlString.length() == 0) return null; 

     Bitmap bitmap = null; 
     URL url = null; 

     try { 
      url = new URL(urlString); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 

     try { 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      conn.setDoInput(true); 
      conn.connect(); 
      InputStream is = conn.getInputStream(); 
      bitmap = BitmapFactory.decodeStream(is); 
      is.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return bitmap; 
    } 

    public static void loadToView(String url, ImageView view) { 
     if (url == null || url.length() == 0) return; 
     if (mMemoryCache == null) { 
      mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
       @Override 
       protected int sizeOf(String key, Bitmap bitmap) { 
        return (bitmap.getRowBytes() * bitmap.getHeight()); 
       } 
      }; 
     } 

     Bitmap bitmap = getBitmapFromMemCache(url); 
     if (bitmap == null) { 
      final AsyncLoader task = (AsyncLoader) new AsyncLoader(view); 
      view.setTag(task); 
      task.execute(url); 
     } else { 
      view.setImageBitmap(bitmap); 
     } 
    } 
} 

用法:

Image.loadToView("http://image_url", (ImageView) view.findViewById(R.id.img_thumbnail)); 

這是怎麼看我的BaseAdapter getView

@Override 
public View getView(final int position, View view, ViewGroup parent) { 
    if (view == null) view = inflater.inflate(R.layout.list_item, null); 

    ((TextView) view.findViewById(R.id.txt_name)).setText(filtered_data.get(position).name); 

    Image.loadToView("http://graph.facebook.com/" + filtered_data.get(position).id + "/picture", (ImageView) view.findViewById(R.id.img_thumbnail)); 

    return view; 
} 
+0

嘗試,而它的downoloading –

+0

設置爲null,imageview的,但我想有一個默認的圖像,如果它不存在?無論如何,我會試試這個...... – norman784

+0

你能從適配器顯示'getView'方法嗎? –

回答

3

我把它弄清楚讀了很多關於列表視圖圖像問題,其相關的listview回收,一些相關的帖子:

我已經添加在onPostExecute方法else語句,如果標籤是不是一個設置好的標籤上我取消它。

固定的代碼及其

public class Image { 
    private static LruCache<String, Bitmap>  mMemoryCache = null; 
    private static int       cacheSize  = 1024 * 1024 * 10; 

    private static class AsyncLoader extends AsyncTask<String, Void, Bitmap> { 
     private ImageView mTarget; 

     public AsyncLoader(ImageView target) { 
      this.mTarget = target; 
     } 

     @Override 
     protected void onPreExecute() { 
      mTarget.setTag(this); 
     } 

     @Override 
     protected Bitmap doInBackground(String...urls) { 
      String url = urls[0]; 

      Bitmap result = null; 

      if (url != null) { 
       result = load(url); 

       if (result != null) { 
        mMemoryCache.put(url, result); 
       } 
      } 

      return result; 
     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      if (mTarget.getTag() == this) { 
       mTarget.setTag(null); 
       if (result != null) mTarget.setImageBitmap(result); 
      } else if (mTarget.getTag() != null) { 
       ((AsyncLoader) mTarget.getTag()).cancel(true); 
       mTarget.setTag(null); 
      } 
     } 
    } 

    public static Bitmap load(String urlString) { 
     if (urlString == null || urlString.length() == 0) return null; 

     Bitmap bitmap = null; 
     URL url = null; 

     try { 
      url = new URL(urlString); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 

     try { 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      conn.setDoInput(true); 
      conn.connect(); 
      InputStream is = conn.getInputStream(); 
      bitmap = BitmapFactory.decodeStream(is); 
      is.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return bitmap; 
    } 

    public static void loadToView(String url, ImageView view) { 
     if (url == null || url.length() == 0) return; 
     if (mMemoryCache == null) { 
      mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
       @Override 
       protected int sizeOf(String key, Bitmap bitmap) { 
        return (bitmap.getRowBytes() * bitmap.getHeight()); 
       } 
      }; 
     } 

     Bitmap bitmap = getBitmapFromMemCache(url); 
     if (bitmap == null) { 
      final AsyncLoader task = (AsyncLoader) new AsyncLoader(view); 
      view.setTag(task); 
      task.execute(url); 
     } else { 
      view.setImageBitmap(bitmap); 
     } 
    } 
} 

我認爲谷歌需要解決這個問題或提供一個更清潔的解決辦法,因爲(在我看來),谷歌的失敗上建立的東西,開發人員只需要關心建立自己的應用程序,而不是失去的時間想辦法解決問題的SDK