GridView使用Adapter異步加載圖片下拉亂跳

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

注意  java

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的下拉不會出現亂跳的問題。  汗啊,整了一天才發現這個問題所在。記錄下來,以示後人。 ide

相關文章
相關標籤/搜索