listview中getview异步加载网络图片

前言:本以为异步加载挺简单,因为网上代码多,但真想要做好,还真不那么简单,从看代码到弄懂再到自己写,实在是有太多的东西需要学了,用了两天的时间,终于弄出来了,因为用到回调函数,所以理解起来可能难度有点大,讲起来也不太好讲,我尽力讲的明白些,其实还是要多看代码,自己摸索摸索,动手写写就什么都理解了。这篇我们只讲怎样实现异步加载,对于滑动时停止加载的事下篇再讲。

实现效果:

1、异步加载图片,在加载图片时,先加载一个默认的图片,然后在后台加载图片,加载完成后显示出来;

2、当用户在滑动时,停止加载图片的线程,当停止滑动时,看哪几个ITEM在显示屏内,只加载这几个,其它线程保持阻止;(下篇再讲)

效果图:

          刚开始加载时                          向下划动(新划出来的是空白块)           停划,加载完成

listview中getview异步加载网络图片  listview中getview异步加载网络图片  listview中getview异步加载网络图片

一、XML

1、main.xml

 

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:orientation="vertical" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="fill_parent" 
  6.    
  7.     <ListView android:id="@+id/list"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent" /> 
  10. </LinearLayout
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    <ListView android:id="@+id/list" 

        android:layout_width="fill_parent" 

        android:layout_height="fill_parent" />

</LinearLayout>

 

2、列表子项XML(book_item_adapter.xml)

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="fill_parent" 
  4.     android:layout_height="70.0dip" 
  5.     android:background="@drawable/item" 
  6.     android:drawingCacheQuality="high" 
  7.     android:minHeight="70.0dip" 
  8.     android:orientation="horizontal"
  9.  
  10.     <ImageView 
  11.         android:id="@+id/sItemIcon" 
  12.         android:layout_width="42.0dip" 
  13.         android:layout_height="54.0dip" 
  14.         android:layout_margin="10.0dip" 
  15.         android:background="@drawable/rc_item_bg" 
  16.         android:padding="2.0dip" 
  17.         android:scaleType="fitXY" /> 
  18.  
  19.     <TextView 
  20.         android:text="斗破苍穹" 
  21.         android:id="@+id/sItemTitle" 
  22.         android:layout_width="fill_parent" 
  23.         android:layout_height="30.0dip" 
  24.         android:layout_alignTop="@+id/sItemIcon" 
  25.         android:layout_toRightOf="@+id/sItemIcon" 
  26.         android:gravity="center_vertical" 
  27.         android:singleLine="true" 
  28.         android:textColor="#ffffff" 
  29.         android:textSize="18.0sp" /> 
  30. </RelativeLayout
<?xml version="1.0" encoding="UTF-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="70.0dip"

    android:background="@drawable/item"

    android:drawingCacheQuality="high"

    android:minHeight="70.0dip"

    android:orientation="horizontal" >



    <ImageView

        android:id="@+id/sItemIcon"

        android:layout_width="42.0dip"

        android:layout_height="54.0dip"

        android:layout_margin="10.0dip"

        android:background="@drawable/rc_item_bg"

        android:padding="2.0dip"

        android:scaleType="fitXY" />



    <TextView

        android:text="斗破苍穹"

        android:id="@+id/sItemTitle"

        android:layout_width="fill_parent"

        android:layout_height="30.0dip"

        android:layout_alignTop="@+id/sItemIcon"

        android:layout_toRightOf="@+id/sItemIcon"

        android:gravity="center_vertical"

        android:singleLine="true"

        android:textColor="#ffffff"

        android:textSize="18.0sp" />

</RelativeLayout>

二、JAVA代码

1、主页面代码(AsyncListImage.java)

 

 

  1. package cn.wangmeng.test; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. import android.app.Activity; 
  7. import android.os.Bundle; 
  8. import android.widget.ListView; 
  9.  
  10. public class AsyncListImage extends Activity { 
  11.     private ListView list; 
  12.     @Override 
  13.     public void onCreate(Bundle savedInstanceState) { 
  14.         super.onCreate(savedInstanceState); 
  15.         setContentView(R.layout.main); 
  16.         list=(ListView)findViewById(R.id.list); 
  17.         List<ImageAndText> dataArray=new ArrayList<ImageAndText>(); 
  18.         for (int i = 0; i < 100; i++) { 
  19.              ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test"); 
  20.              ImageAndText test1=new ImageAndText("http://www.pfwx.com/files/article/image/0/54/54s.jpg", "test1"); 
  21.              ImageAndText test2=new ImageAndText("http://www.pfwx.com/files/article/image/0/4/4s.jpg","test2"); 
  22.              ImageAndText test3=new ImageAndText("http://www.pfwx.com/files/article/image/9/9760/9760s.jpg","test3"); 
  23.              ImageAndText test4=new ImageAndText("http://www.pfwx.com/files/article/image/3/3382/3382s.jpg","test4"); 
  24.              ImageAndText test5=new ImageAndText("http://www.pfwx.com/files/article/image/3/3237/3237s.jpg","test5"); 
  25.              dataArray.add(test); 
  26.              dataArray.add(test1); 
  27.              dataArray.add(test2);   
  28.              dataArray.add(test3);   
  29.              dataArray.add(test4);   
  30.              dataArray.add(test5);   
  31.               
  32.         } 
  33.         
  34.         ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list); 
  35.         list.setAdapter(adapter); 
  36.          
  37.     } 
package cn.wangmeng.test;



import java.util.ArrayList;

import java.util.List;



import android.app.Activity;

import android.os.Bundle;

import android.widget.ListView;



public class AsyncListImage extends Activity {

	private ListView list;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        list=(ListView)findViewById(R.id.list);

        List<ImageAndText> dataArray=new ArrayList<ImageAndText>();

        for (int i = 0; i < 100; i++) {

        	 ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");

             ImageAndText test1=new ImageAndText("http://www.pfwx.com/files/article/image/0/54/54s.jpg", "test1");

             ImageAndText test2=new ImageAndText("http://www.pfwx.com/files/article/image/0/4/4s.jpg","test2");

             ImageAndText test3=new ImageAndText("http://www.pfwx.com/files/article/image/9/9760/9760s.jpg","test3");

             ImageAndText test4=new ImageAndText("http://www.pfwx.com/files/article/image/3/3382/3382s.jpg","test4");

             ImageAndText test5=new ImageAndText("http://www.pfwx.com/files/article/image/3/3237/3237s.jpg","test5");

             dataArray.add(test);

             dataArray.add(test1);

             dataArray.add(test2);	

             dataArray.add(test3);	

             dataArray.add(test4);	

             dataArray.add(test5);	

             

		}

       

        ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);

        list.setAdapter(adapter);

        

    }

}

 

2、ImageAndText.java

 

 

  1. package cn.wangmeng.test; 
  2.  
  3. public class ImageAndText { 
  4.         private String imageUrl; 
  5.         private String text; 
  6.  
  7.         public ImageAndText(String imageUrl, String text) { 
  8.             this.imageUrl = imageUrl; 
  9.             this.text = text; 
  10.         } 
  11.         public String getImageUrl() { 
  12.             return imageUrl; 
  13.         } 
  14.         public String getText() { 
  15.             return text; 
  16.         } 
package cn.wangmeng.test;



public class ImageAndText {

	    private String imageUrl;

	    private String text;



	    public ImageAndText(String imageUrl, String text) {

	        this.imageUrl = imageUrl;

	        this.text = text;

	    }

	    public String getImageUrl() {

	        return imageUrl;

	    }

	    public String getText() {

	        return text;

	    }

}

上面两个代码一块讲 1、ImageAndText类是用来存储要与XML绑定的图片地址和名字地址的。

 

2、将所有的地址都放在一个List里面(dataArray),然后将其传入ImageAndTextListAdapter()函数中;可见这个ImageAndTextListAdapter()函数是根据传进去的dataArray生成对应的Adapter的

3、然后将ImageAndTextListAdapter()返回的Adapter与listView绑定

3、ImageAndTextListAdapter.java

 

这是重写于baseAdapter的类,由于重写于baseAdapter,所以有几个必须重写的函数,getCount()、getItem()、getItemId()、getView(),我们先把总体代码写出来,只讲一个getView()函数,其实函数就不讲了,先着重说下getView()函数在什么时候被系统调用:

getView()函数在什么时候被系统调用:

注意一点是android系统在显示列表时,并不是把所有代表都显示出来,让你随便划,划到哪是哪;而是根据当前的在划到的ITEM,调用当前ITEM的getView()来显示它。

全部代码:

 

  1. package cn.wangmeng.test; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. import cn.wangmeng.test.AsyncImageLoader.ImageCallback; 
  7.  
  8. import android.app.Activity; 
  9. import android.graphics.drawable.Drawable; 
  10. import android.util.Log; 
  11. import android.view.LayoutInflater; 
  12. import android.view.View; 
  13. import android.view.ViewGroup; 
  14. import android.widget.ArrayAdapter; 
  15. import android.widget.BaseAdapter; 
  16. import android.widget.ImageView; 
  17. import android.widget.ListView; 
  18. import android.widget.TextView; 
  19.  
  20. public class ImageAndTextListAdapter extends BaseAdapter { 
  21.  
  22.         private LayoutInflater inflater; 
  23.         private ListView listView; 
  24.         private AsyncImageLoader asyncImageLoader; 
  25.  
  26.         private List<ImageAndText> dataArray=new ArrayList<ImageAndText>(); 
  27.  
  28.         public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) { 
  29.  
  30.             this.listView = listView; 
  31.             asyncImageLoader = new AsyncImageLoader(); 
  32.             inflater = activity.getLayoutInflater(); 
  33.             dataArray=imageAndTexts; 
  34.         } 
  35.          
  36.         @Override 
  37.         public int getCount() { 
  38.             // TODO Auto-generated method stub  
  39.             return dataArray.size(); 
  40.         } 
  41.         @Override 
  42.         public Object getItem(int position) { 
  43.             // TODO Auto-generated method stub  
  44.             if(position >= getCount()){ 
  45.                 return null; 
  46.             } 
  47.             return dataArray.get(position); 
  48.         } 
  49.         @Override 
  50.         public long getItemId(int position) { 
  51.             // TODO Auto-generated method stub  
  52.             return position; 
  53.         } 
  54.  
  55.         //不需要ViewHolder版,直接将ImageAndText与XML资源关联起来  
  56.         public View getView(int position, View convertView, ViewGroup parent) { 
  57.             if (convertView == null) { 
  58.                  convertView = inflater.inflate(R.layout.book_item_adapter, null); 
  59.             } 
  60.             convertView.setTag(position); 
  61.              
  62.             ImageAndText imageAndText = (ImageAndText) getItem(position); 
  63.             String imageUrl = imageAndText.getImageUrl(); 
  64.              
  65.             TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle);  
  66.             // 将XML视图项与用户输入的URL和文本在绑定  
  67.             textView.setText(imageAndText.getText());//加载TEXT  
  68.             ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon); 
  69.             iv.setBackgroundResource(R.drawable.rc_item_bg);//在初始化时,先把背景图片设置成默认背景,  
  70.                                         //否则在下拉时会随机匹配背景,不美观  
  71.      
  72.             asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() { 
  73.                 @Override 
  74.                 public void onImageLoad(Integer pos, Drawable drawable) { 
  75.                     View view = listView.findViewWithTag(pos); 
  76.                     if(view != null){ 
  77.                         ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon); 
  78.                         iv.setBackgroundDrawable(drawable); 
  79.                     } 
  80.                 } 
  81.                 //加载不成功的图片处理      
  82.                 @Override 
  83.                 public void onError(Integer pos) { 
  84.                     View view = listView.findViewWithTag(pos); 
  85.                     if(view != null){ 
  86.                         ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon); 
  87.                         iv.setBackgroundResource(R.drawable.rc_item_bg); 
  88.                     } 
  89.                 } 
  90.                  
  91.             }); 
  92.             return convertView; 
  93.         } 
package cn.wangmeng.test;



import java.util.ArrayList;

import java.util.List;



import cn.wangmeng.test.AsyncImageLoader.ImageCallback;



import android.app.Activity;

import android.graphics.drawable.Drawable;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;



public class ImageAndTextListAdapter extends BaseAdapter {



		private LayoutInflater inflater;

	    private ListView listView;

	    private AsyncImageLoader asyncImageLoader;



	    private List<ImageAndText> dataArray=new ArrayList<ImageAndText>();



	    public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {



	        this.listView = listView;

	        asyncImageLoader = new AsyncImageLoader();

	        inflater = activity.getLayoutInflater();

	        dataArray=imageAndTexts;

	    }

	    

		@Override

		public int getCount() {

			// TODO Auto-generated method stub

			return dataArray.size();

		}

		@Override

		public Object getItem(int position) {

			// TODO Auto-generated method stub

			if(position >= getCount()){

				return null;

			}

			return dataArray.get(position);

		}

		@Override

		public long getItemId(int position) {

			// TODO Auto-generated method stub

			return position;

		}



	    //不需要ViewHolder版,直接将ImageAndText与XML资源关联起来

	    public View getView(int position, View convertView, ViewGroup parent) {

	    	if (convertView == null) {

	        	 convertView = inflater.inflate(R.layout.book_item_adapter, null);

	        }

	        convertView.setTag(position);

	        

	        ImageAndText imageAndText = (ImageAndText) getItem(position);

	        String imageUrl = imageAndText.getImageUrl();

	        

	        TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle); 

	        // 将XML视图项与用户输入的URL和文本在绑定

	        textView.setText(imageAndText.getText());//加载TEXT

	        ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);

	        iv.setBackgroundResource(R.drawable.rc_item_bg);//在初始化时,先把背景图片设置成默认背景,

	        							//否则在下拉时会随机匹配背景,不美观

	

	        asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {

	        	@Override

	    		public void onImageLoad(Integer pos, Drawable drawable) {

	    			View view = listView.findViewWithTag(pos);

	    			if(view != null){

	    				ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);

	    				iv.setBackgroundDrawable(drawable);

	    			}

	    		}

	        	//加载不成功的图片处理	

				@Override

				public void onError(Integer pos) {

					View view = listView.findViewWithTag(pos);

					if(view != null){

						ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);

						iv.setBackgroundResource(R.drawable.rc_item_bg);

					}

				}

	        	

	        });

	        return convertView;

	    }

}

我们着重看getView()函数 1、看这段:

 

 

  1. if (convertView == null) { 
  2.      convertView = inflater.inflate(R.layout.book_item_adapter, null); 
  3. convertView.setTag(position); 
  4.  
  5. ImageAndText imageAndText = (ImageAndText) getItem(position); 
  6. String imageUrl = imageAndText.getImageUrl(); 
  7.  
  8. TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle);  
  9. // 将XML视图项与用户输入的URL和文本在绑定  
  10. textView.setText(imageAndText.getText());//加载TEXT  
  11. ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon); 
  12. iv.setBackgroundResource(R.drawable.rc_item_bg); 
if (convertView == null) {

	 convertView = inflater.inflate(R.layout.book_item_adapter, null);

}

convertView.setTag(position);



ImageAndText imageAndText = (ImageAndText) getItem(position);

String imageUrl = imageAndText.getImageUrl();



TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle); 

// 将XML视图项与用户输入的URL和文本在绑定

textView.setText(imageAndText.getText());//加载TEXT

ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);

iv.setBackgroundResource(R.drawable.rc_item_bg);

这段代码没什么特别的就是将前面dataArray的信息与XML的元素项对应起来,并绑定,最关键的是下面这段,下面这个方法才是实现异步加载图片的关键:

  1. asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() { 
  2.     @Override 
  3.     public void onImageLoad(Integer pos, Drawable drawable) { 
  4.         View view = listView.findViewWithTag(pos); 
  5.         if(view != null){ 
  6.             ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon); 
  7.             iv.setBackgroundDrawable(drawable); 
  8.         } 
  9.     } 
  10.     //加载不成功的图片处理      
  11.     @Override 
  12.     public void onError(Integer pos) { 
  13.         View view = listView.findViewWithTag(pos); 
  14.         if(view != null){ 
  15.             ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon); 
  16.             iv.setBackgroundResource(R.drawable.rc_item_bg); 
  17.         } 
  18.     } 
  19.      
  20. }); 
asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {

	@Override

	public void onImageLoad(Integer pos, Drawable drawable) {

		View view = listView.findViewWithTag(pos);

		if(view != null){

			ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);

			iv.setBackgroundDrawable(drawable);

		}

	}

	//加载不成功的图片处理	

	@Override

	public void onError(Integer pos) {

		View view = listView.findViewWithTag(pos);

		if(view != null){

			ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);

			iv.setBackgroundResource(R.drawable.rc_item_bg);

		}

	}

	

});

这段代码的奇特之处在于,利用AsyncImageLoader类的实例(asyncImageLoader),调用方法loadDrawable()方法,就实现了加载后图像的绑定;好神奇,仔细看他是怎么做到的。这里先注意的有两点: (1)、传进去的参数,当前项的位置(position),当前图片的URL(imageUrl),一个名称为ImageCallback()接口函数;

 

(2)、ImageCallback()接口函数里的两个被重写的函数onImageLoad()和onError()

3、AsyncImageLoader.java

从上面的讲解也应该能猜到这个类,主要的功能就是加载图片,然后成功后更新UI;

先看全部代码,然后再逐步讲

 

  1. package cn.wangmeng.test; 
  2.  
  3. import java.io.IOException; 
  4. import java.io.InputStream; 
  5. import java.lang.ref.SoftReference; 
  6. import java.net.URL; 
  7. import java.util.HashMap; 
  8.  
  9. import android.graphics.drawable.Drawable; 
  10. import android.os.Handler; 
  11.  
  12. public class AsyncImageLoader { 
  13.     final Handler handler = new Handler(); 
  14.     private HashMap<String, SoftReference<Drawable>> imageCache; 
  15.     public AsyncImageLoader() { 
  16.         imageCache = new HashMap<String, SoftReference<Drawable>>();//图片缓存  
  17.     } 
  18.      
  19.     // 回调函数  
  20.     public interface ImageCallback { 
  21.         public void onImageLoad(Integer t, Drawable drawable); 
  22.         public void onError(Integer t); 
  23.     } 
  24.  
  25.     public Drawable loadDrawable(final Integer pos, final String imageUrl, 
  26.              final ImageCallback imageCallback) { 
  27.         new Thread() { 
  28.             @Override 
  29.             public void run() { 
  30.                  
  31.                 LoadImg(pos, imageUrl, imageCallback); 
  32.  
  33.             } 
  34.         }.start(); 
  35.         return null; 
  36.     }// loadDrawable---end  
  37.  
  38.     public void LoadImg(final Integer pos, final String imageUrl, 
  39.             final ImageCallback imageCallback) { 
  40.         // 首先判断是否在缓存中  
  41.         // 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现  
  42.         if (imageCache.containsKey(imageUrl)) { 
  43.             SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
  44.             final Drawable drawable = softReference.get(); 
  45.             if (drawable != null) { 
  46.                 handler.post(new Runnable() { 
  47.                     @Override 
  48.                     public void run() { 
  49.                         imageCallback.onImageLoad(pos, drawable); 
  50.                     } 
  51.                 }); 
  52.                 return; 
  53.             } 
  54.         } 
  55.         // 尝试从URL中加载  
  56.         try { 
  57.             final Drawable drawable = loadImageFromUrl(imageUrl); 
  58.             if (drawable != null) { 
  59.                 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); 
  60.             } 
  61.             handler.post(new Runnable() { 
  62.                 @Override 
  63.                 public void run() { 
  64.                         imageCallback.onImageLoad(pos, drawable); 
  65.                 } 
  66.             }); 
  67.         } catch (IOException e) { 
  68.             handler.post(new Runnable() { 
  69.                 @Override 
  70.                 public void run() { 
  71.                     imageCallback.onError(pos); 
  72.                 } 
  73.             }); 
  74.             e.printStackTrace(); 
  75.         } 
  76.  
  77.     } 
  78.  
  79.     // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数  
  80.     public static Drawable loadImageFromUrl(String url) throws IOException { 
  81.         URL m; 
  82.         InputStream i = null; 
  83.         m = new URL(url); 
  84.         i = (InputStream) m.getContent(); 
  85.         Drawable d = Drawable.createFromStream(i, "src"); 
  86.         return d; 
  87.     } 
  88.  
package cn.wangmeng.test;



import java.io.IOException;

import java.io.InputStream;

import java.lang.ref.SoftReference;

import java.net.URL;

import java.util.HashMap;



import android.graphics.drawable.Drawable;

import android.os.Handler;



public class AsyncImageLoader {

	final Handler handler = new Handler();

	private HashMap<String, SoftReference<Drawable>> imageCache;

	public AsyncImageLoader() {

		imageCache = new HashMap<String, SoftReference<Drawable>>();//图片缓存

	}

	

	// 回调函数

	public interface ImageCallback {

		public void onImageLoad(Integer t, Drawable drawable);

		public void onError(Integer t);

	}



	public Drawable loadDrawable(final Integer pos, final String imageUrl,

			 final ImageCallback imageCallback) {

		new Thread() {

			@Override

			public void run() {

				

				LoadImg(pos, imageUrl, imageCallback);



			}

		}.start();

		return null;

	}// loadDrawable---end



	public void LoadImg(final Integer pos, final String imageUrl,

			final ImageCallback imageCallback) {

		// 首先判断是否在缓存中

		// 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现

		if (imageCache.containsKey(imageUrl)) {

			SoftReference<Drawable> softReference = imageCache.get(imageUrl);

			final Drawable drawable = softReference.get();

			if (drawable != null) {

				handler.post(new Runnable() {

					@Override

					public void run() {

						imageCallback.onImageLoad(pos, drawable);

					}

				});

				return;

			}

		}

		// 尝试从URL中加载

		try {

			final Drawable drawable = loadImageFromUrl(imageUrl);

			if (drawable != null) {

				imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));

			}

			handler.post(new Runnable() {

				@Override

				public void run() {

						imageCallback.onImageLoad(pos, drawable);

				}

			});

		} catch (IOException e) {

			handler.post(new Runnable() {

				@Override

				public void run() {

					imageCallback.onError(pos);

				}

			});

			e.printStackTrace();

		}



	}



	// 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数

	public static Drawable loadImageFromUrl(String url) throws IOException {

		URL m;

		InputStream i = null;

		m = new URL(url);

		i = (InputStream) m.getContent();

		Drawable d = Drawable.createFromStream(i, "src");

		return d;

	}



}

分别讲解 1、先看这段代码

 

 

  1. // 回调函数  
  2. public interface ImageCallback { 
  3.     public void onImageLoad(Integer t, Drawable drawable); 
  4.     public void onError(Integer t); 
  5.  
  6. public Drawable loadDrawable(final Integer pos, final String imageUrl, 
  7.          final ImageCallback imageCallback) { 
  8.     new Thread() { 
  9.         @Override 
  10.         public void run() { 
  11.              
  12.             LoadImg(pos, imageUrl, imageCallback); 
  13.  
  14.         } 
  15.     }.start(); 
  16.     return null; 
  17. }// loadDrawable---end 
	// 回调函数

	public interface ImageCallback {

		public void onImageLoad(Integer t, Drawable drawable);

		public void onError(Integer t);

	}



	public Drawable loadDrawable(final Integer pos, final String imageUrl,

			 final ImageCallback imageCallback) {

		new Thread() {

			@Override

			public void run() {

				

				LoadImg(pos, imageUrl, imageCallback);



			}

		}.start();

		return null;

	}// loadDrawable---end

(1)首先注意,刚才我们调用的loadDrawable()函数,里面初始化并运行了一个线程,而这个线程的里面只有一个函数LoadImg(),对于这个函数下面我们具体讲,它的主要功能就是加载图片,然后更新UI (2)上面也看出了ImageCallback是一个接口,而里面的两个函数onImageLoad()和onError()在这里是没有具体实现的,那在哪里实现呢,当然是我们上面的ImageAndTextListAdapter.java里面了,等下我们具体会再讲。

 

再往下看

 

  1. // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数  
  2.     public static Drawable loadImageFromUrl(String url) throws IOException { 
  3.         URL m; 
  4.         InputStream i = null; 
  5.         m = new URL(url); 
  6.         i = (InputStream) m.getContent(); 
  7.         Drawable d = Drawable.createFromStream(i, "src"); 
  8.         return d; 
  9.     } 
  10.      
  11. public void LoadImg(final Integer pos, final String imageUrl, 
  12.         final ImageCallback imageCallback) { 
  13.     // 首先判断是否在缓存中  
  14.     // 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现  
  15.     if (imageCache.containsKey(imageUrl)) { 
  16.         SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
  17.         final Drawable drawable = softReference.get(); 
  18.         if (drawable != null) { 
  19.             handler.post(new Runnable() { 
  20.                 @Override 
  21.                 public void run() { 
  22.                     imageCallback.onImageLoad(pos, drawable); 
  23.                 } 
  24.             }); 
  25.             return; 
  26.         } 
  27.     } 
  28.     // 尝试从URL中加载  
  29.     try { 
  30.         final Drawable drawable = loadImageFromUrl(imageUrl); 
  31.         if (drawable != null) { 
  32.             imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); 
  33.         } 
  34.         handler.post(new Runnable() { 
  35.             @Override 
  36.             public void run() { 
  37.                     imageCallback.onImageLoad(pos, drawable); 
  38.             } 
  39.         }); 
  40.     } catch (IOException e) { 
  41.         handler.post(new Runnable() { 
  42.             @Override 
  43.             public void run() { 
  44.                 imageCallback.onError(pos); 
  45.             } 
  46.         }); 
  47.         e.printStackTrace(); 
  48.     } 
  49.  
	// 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数

		public static Drawable loadImageFromUrl(String url) throws IOException {

			URL m;

			InputStream i = null;

			m = new URL(url);

			i = (InputStream) m.getContent();

			Drawable d = Drawable.createFromStream(i, "src");

			return d;

		}

		

	public void LoadImg(final Integer pos, final String imageUrl,

			final ImageCallback imageCallback) {

		// 首先判断是否在缓存中

		// 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现

		if (imageCache.containsKey(imageUrl)) {

			SoftReference<Drawable> softReference = imageCache.get(imageUrl);

			final Drawable drawable = softReference.get();

			if (drawable != null) {

				handler.post(new Runnable() {

					@Override

					public void run() {

						imageCallback.onImageLoad(pos, drawable);

					}

				});

				return;

			}

		}

		// 尝试从URL中加载

		try {

			final Drawable drawable = loadImageFromUrl(imageUrl);

			if (drawable != null) {

				imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));

			}

			handler.post(new Runnable() {

				@Override

				public void run() {

						imageCallback.onImageLoad(pos, drawable);

				}

			});

		} catch (IOException e) {

			handler.post(new Runnable() {

				@Override

				public void run() {

					imageCallback.onError(pos);

				}

			});

			e.printStackTrace();

		}



	}

(1)、loadImageFromUrl()函数,就是根据URL到网上加载图片,然后返回图片流Drawable类型变量 (2)、对于LoadImg()我们再拆一下,先看如何在缓存中加载

 

 

  1. if (imageCache.containsKey(imageUrl)) { 
  2.     SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
  3.     final Drawable drawable = softReference.get(); 
  4.     if (drawable != null) { 
  5.         handler.post(new Runnable() { 
  6.             @Override 
  7.             public void run() { 
  8.                 imageCallback.onImageLoad(pos, drawable); 
  9.             } 
  10.         }); 
  11.         return; 
  12.     } 
		if (imageCache.containsKey(imageUrl)) {

			SoftReference<Drawable> softReference = imageCache.get(imageUrl);

			final Drawable drawable = softReference.get();

			if (drawable != null) {

				handler.post(new Runnable() {

					@Override

					public void run() {

						imageCallback.onImageLoad(pos, drawable);

					}

				});

				return;

			}

		}

注意:

 

1、在这里就已经得到了图像

  1. SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
  2. final Drawable drawable = softReference.get(); 
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);

			final Drawable drawable = softReference.get();

2、得到图像之后就到了这段代码:

 

 

  1. if (drawable != null) { 
  2.     handler.post(new Runnable() { 
  3.         @Override 
  4.         public void run() { 
  5.             imageCallback.onImageLoad(pos, drawable); 
  6.         } 
  7.     }); 
  8.     return; 
			if (drawable != null) {

				handler.post(new Runnable() {

					@Override

					public void run() {

						imageCallback.onImageLoad(pos, drawable);

					}

				});

				return;

			}

当我们得到图像之后,调用imageCallback.onImageLoad(pos, drawable);来更新UI,由于我们再回来看看ImageAndTextListAdapter.java中的代码

 

 

  1. asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() { 
  2.     @Override 
  3.     public void onImageLoad(Integer pos, Drawable drawable) { 
  4.         View view = listView.findViewWithTag(pos); 
  5.         if(view != null){ 
  6.             ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon); 
  7.             iv.setBackgroundDrawable(drawable); 
  8.         } 
  9.     } 
  10.      
  11. }); 
asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {

	@Override

	public void onImageLoad(Integer pos, Drawable drawable) {

		View view = listView.findViewWithTag(pos);

		if(view != null){

			ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);

			iv.setBackgroundDrawable(drawable);

		}

	}

	

});

看到了吧,就是把得到的drawable与加载到UI中!!!!这就实现了回调

 

OK,就到这吧,OnError()的原理一样,只不过是对程序没有加载到图片时应该怎么处理,其实就是当没有加载到图片时就是默认图片代替。
下面给出源码:http://download.csdn.net/detail/harvic880925/6802241(不要分,仅供分享)

 

请大家尊重作者板权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/17766027 ,谢谢!

你可能感兴趣的:(ListView)