2014-07-08 20 views
1

我有一個ListView,我正在使用支持庫中的Palette。當使用BitmapFactory.decodeStream從url生成位圖時,會引發異常(UI線程上的網絡)或可能非常昂貴。我如何使這種異步?我想不出有效的方法來做到這一點。什麼是最好的方法?ListView Android和Picasso中的調色板

@Override 
    public View getView(int position, View convertView, ViewGroup viewGroup) { 
     final ViewHolder holder; 
     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.item_grid, null); 
      holder = new ViewHolder(); 
      holder.image = (ImageView) convertView.findViewById(R.id.img_photo); 
      holder.bg = (LinearLayout) convertView.findViewById(R.id.bg_title); 
      holder.text = (TextView) convertView.findViewById(R.id.txt_title); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     Picasso.with(mContext) 
       .load(mShows.get(position).poster) 
       .into(holder.image); 

     try { 
      URL url = new URL(mShows.get(position).poster); 
      Bitmap bitmap = BitmapFactory.decodeStream(
        url.openConnection().getInputStream()); // Too expensive!!! 
      Palette palette = Palette.generate(bitmap); 

      holder.text.setText(mShows.get(position).title); 
      holder.text.setTextColor(palette.getVibrantColor().getRgb()); 

      holder.bg.setAlpha(0.4f); 
      holder.bg.setBackgroundColor(palette.getDarkMutedColor().getRgb()); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return convertView; 
    } 

回答

5

你可以用畢加索的into(...)Callback參數在圖像已成功加載:

Picasso.with(mContext) 
      .load(mShows.get(position).poster) 
      .into(holder.image, new Callback() { 

    @Override public void onSuccess() { 
     Bitmap bitmap = ((BitmapDrawable)holder.image.getDrawable()).getBitmap(); 
     // do your processing here.... 
    } 

    @Override public void onError() { 
     // reset your views to default colors, etc. 
    } 

}); 
+0

這節省了大量的工作。 – chip

0

嘗試做網絡和位圖解碼的東西,在一個工作線程,異步通知回來時,你得到的位圖,你還需要一個位圖緩存避免重複解碼工作。 一個簡單的實現是這樣的:

Interface IBitmapCache { 
    Bitmap get(String key); 
    put(String key, Bitmap map); 
} 

Class YourAdapter { 

    Class ViewHolder { 
     //your other views 
     //use url as key. 
     String url; 
    } 

    IBitmapCache mCache; 

    //you need to hold an instance of your listview here. 
    WeakReference<ListView> mAttachedListView; 

    View getView() { 
     //... handle other things 
     Bitmap bitmap = mCache.get(url); 
     if (bitmap == null) { 
      //retrieve bitmap asynchronous 
     } 
    } 

    //callback when bitmap is retrieved 
    void onBitmapRetrived(String url, Bitmap bitmap) { 
     if (mAttachedListView.get() != null) { 
      final ListView list = mAttachedListView.get(); 
      final int count = list.getLastVisiblePosition() - list.getFirstVisiblePosition + 1; 
      for (int i = 0; i < count; i++) { 
       View v = lv.getChildAt(i); 
       if (v == null) { 
        continue; 
       } 
       ViewHolder holder = (ViewHolder) v.getTag(); 
       if (url.equals(holder.url)) { 
        //do your Palette related things here. 
        break; 
       } 
      } 
     } 
    } 
} 

有2件更多的事情,你應該做的,把你的解碼位圖到您的位圖緩存,回調設置爲你的工作線程,並確保它被稱爲在UI線程這可以通過Handler輕鬆實現。