GridView常用于列表展示图片,然而图片的加载又是很慢的,因此需要做异步加载。使用 Base Adapter来进行异步加载的话,常常的写法是:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView image = null;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(
R.layout.item, parent, false);
} else {
imageView = (ImageView) convertView;
}
asynLoadBitmap(imageView,position);//异步去加载图片
}
private HashMap<Int position,Bitmap> cache = null;
public void asynLoadBitmap(ImageView image){
Bitmap bit = cache.get(position);
if(bit ==null){
//需要设置为默认的图片来显示
image.setImageBitmap(blank);
//使用Task或者是线程去加载图片
new LoadTask().execute();
}else{
image.setImageBitmap(bit);
}
}
注意
image.setImageBitmap(blank);
这一句,这样子设置会有问题, GridView在下拉的时候会出现乱跳的问题。原因是由于GridView使用了缓存机制,下拉传入getView的 convertView是上面一页用过的,这时候虽然调用了setImageBitmap为blank,但是下拉的时候依然会先看到原来的图片(而不是 blank),然后LoadTask加载完成后,又去更新ImageView,就出现了乱跳的情况。这个问题可能是由于Adapter的getVIew函 数是异步在执行,因此导致调用setImageBitmap(blank),不能马上成功。解决方法是
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView image = null;
if (convertView == null) {
imageView = (ImageView) getLayoutInflater().inflate(
R.layout.item, parent, false);
} else {
imageView = (ImageView) convertView;
}
imageView.setTag(position);
asynLoadBitmap(imageView,position);//异步去加载图片
}
private HashMap<Int position,Bitmap> cache = null;
public void asynLoadBitmap(ImageView image){
Bitmap bit = cache.get(position);
if(bit ==null){
//需要设置为默认的图片来显示
setImageBitmap(image,blank,new Handler());
//使用Task或者是线程去加载图片
new LoadTask(image,new Handler(),position).execute();
}else{
image.setImageBitmap(bit);
}
}
public void LoadTask extends Runable(){
ImageView view;
Handler handler;
int position;
public LoadTask(ImageView view,Handler handler,int position){
this.view = view;
this.handler = handler;
this.position = position;
}
public void run(){
Bitmap bit = loadBitmap();
setImageBitmap(view,bit,handler,position);
}
}
private void setImageBitmap(final ImageView view,final Bitmap bit,Handler handler,int position){
if(view.getTag() == position){
handler.post(new Raunable(){
public void run(){
view.setImageBitmap(bit);
}
});
}
}
加了2个地方:
1.更新ImageView的bitmap使用handler.post的方法来更新。这样会比在getView中使用imageView.setImageBitmap来更新得更快。
2.在getView中,更新imageVIew的position。在更新bitmap的时候要先进行比对position。如果对应,则进行更新。
这样做了过后就能保证GridVIew的下拉不会出现乱跳的问题。