http://www.eoeandroid.com/thread-67273-1-1.html

ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码:
Java代码  
package  cn.wangmeng.test;  
    
import  java.io.IOException;    
import  java.io.InputStream;  
import  java.lang.ref.SoftReference;    
import  java.net.MalformedURLException;    
import  java.net.URL;   
import  java.util.HashMap;    

import  android.graphics.drawable.Drawable;   
import  android.os.Handler;  
import  android.os.Message;   

public   class  AsyncImageLoader {    

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

         public  AsyncImageLoader() {    
             imageCache = new  HashMap<String, SoftReference<Drawable>>(); 
         }   
          
         public  Drawable loadDrawable( final  String imageUrl,  final  ImageCallback imageCallback) {    
             if  (imageCache.containsKey(imageUrl)) {    
                 SoftReference<Drawable> softReference = imageCache.get(imageUrl);    
                 Drawable drawable = softReference.get();    
                 if  (drawable !=  null ) {  
                     return  drawable;    
                 }    
             }   
             final  Handler handler =  new  Handler() { 
                 public   void  handleMessage(Message message) {    
                     imageCallback.imageLoaded((Drawable) message.obj, imageUrl);    
                 }    
             };   
             new  Thread() {    
                 @Override     
                 public   void  run() {    - ]# l8 q+ B0 t) {
                     Drawable drawable = loadImageFromUrl(imageUrl);    
                     imageCache.put(imageUrl, new  SoftReference<Drawable>(drawable));    
                     Message message = handler.obtainMessage(0 , drawable);    
                     handler.sendMessage(message);    
                 }  
             }.start();    
             return   null ;    
         }   

        public   static  Drawable loadImageFromUrl(String url) {    
            URL m;    
            InputStream i = null ;
            try  { 
                m = new  URL(url);    
                i = (InputStream) m.getContent();  
            } catch  (MalformedURLException e1) {    
                e1.printStackTrace();   
            } catch  (IOException e) {   
                e.printStackTrace();  
            }    
            Drawable d = Drawable.createFromStream(i, "src" );    
            return  d;    
        }    
          
         public   interface  ImageCallback {    
             public   void  imageLoaded(Drawable imageDrawable, String imageUrl);    
         }    
}  
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。 
几个辅助类文件:
Java代码
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;  
        }    
}   

Java代码  
package  cn.wangmeng.test;

import  android.view.View;    
import  android.widget.ImageView;    
import  android.widget.TextView;    
    
public   class  ViewCache {   
    
        private  View baseView;   
        private  TextView textView;    
        private  ImageView imageView;    

        public  ViewCache(View baseView) {    
            this .baseView = baseView;    
        }    
 
        public  TextView getTextView() {    
            if  (textView ==  null ) {    
                textView = (TextView) baseView.findViewById(R.id.text);   
            }    
            return  textView;  
    
        public  ImageView getImageView() {   
            if  (imageView ==  null ) {    $
                imageView = (ImageView) baseView.findViewById(R.id.image);   
            }    
            return  imageView;  
        }    
    
}    

ViewCache是辅助获取adapter的子元素布局
Java代码  
package  cn.wangmeng.test;    
    
import  java.util.List;    
    
import  cn.wangmeng.test.AsyncImageLoader.ImageCallback;    

import  android.app.Activity;    
import  android.graphics.drawable.Drawable; 
import  android.view.LayoutInflater;   
import  android.view.View;  
import  android.view.ViewGroup;      
import  android.widget.ArrayAdapter;    
import  android.widget.ImageView;    
import  android.widget.ListView;    
import  android.widget.TextView;    
    
public   class  ImageAndTextListAdapter  extends  ArrayAdapter<ImageAndText> {    
    
        private  ListView listView;    
        private  AsyncImageLoader asyncImageLoader;    
    
        public  ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {   
            super (activity,  0 , imageAndTexts);    
            this .listView = listView;    
            asyncImageLoader = new  AsyncImageLoader(); 
        }    

        public  View getView( int  position, View convertView, ViewGroup parent) {    
            Activity activity = (Activity) getContext();    

            // Inflate the views from XML     
            View rowView = convertView;
            ViewCache viewCache;    
            if  (rowView ==  null ) {    
                LayoutInflater inflater = activity.getLayoutInflater();   
                rowView = inflater.inflate(R.layout.image_and_text_row, null );    
                viewCache = new  ViewCache(rowView);   
                rowView.setTag(viewCache);    
            } else  {    
                viewCache = (ViewCache) rowView.getTag();    
            }    
            ImageAndText imageAndText = getItem(position);    

            // Load the image and set it on the ImageView   
            String imageUrl = imageAndText.getImageUrl();   
            ImageView imageView = viewCache.getImageView();  
            imageView.setTag(imageUrl);  
            Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new  ImageCallback() {    
                public   void  imageLoaded(Drawable imageDrawable, String imageUrl) {   
                    ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);    
                    if  (imageViewByTag !=  null ) {    
                        imageViewByTag.setImageDrawable(imageDrawable);    
                    }   
                }    
            });
            if  (cachedImage ==  null ) {    
                imageView.setImageResource(R.drawable.default_image);    
            }else {  
                imageView.setImageDrawable(cachedImage);    
            }    
            // Set the text on the TextView    
            TextView textView = viewCache.getTextView();    
            textView.setText(imageAndText.getText());   
    
            return  rowView;    
        }    
    
}  
ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是 imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应 item,大家仔细阅读就知道了。 
最后贴出布局文件: 
Java代码  
<?xml version= "1.0"  encoding= "utf-8" ?>    
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
              android:orientation="horizontal"     
              android:layout_width="fill_parent"     
              android:layout_height="wrap_content" >    
    
        <ImageView android:id="@+id/image"     
                   android:layout_width="wrap_content"     
                   android:layout_height="wrap_content"     
                   />    
    
        <TextView android:id="@+id/text"   
                  android:layout_width="wrap_content"    
                  android:layout_height="wrap_content" />    
</LinearLayout>

posted on 2011-06-14 15:07  threecc  阅读(85)  评论(0)    收藏  举报