我有一个ListView
,我正在使用支持库中的Palette
。当使用BitmapFactory.decodeStream
从URL生成位图时,这会引发异常(网络在UI线程上)或者可能非常昂贵。我如何使这个异步?我想不出任何有效的方法来做到这一点。什么是最好的方法?
@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;
}
答案 0 :(得分:5)
你可以使用Picasso的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.
}
});
答案 1 :(得分: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;
}
}
}
}
}
你还应该做两件事,把解码后的Bitmap放到你的位图缓存中,设置回调你的工作线程并确保在UI线程上调用它,这可以通过Handler
轻松实现。 / p>