ListView显示网络图片的方法

 

今天在网上找了一整天如何实现ListView显示网络图片的方法

1:显示的图片比较小(1-2张)。这样我觉得不需要使用异步来加载,直接使用位图显示就OK

2:显示的图片比较多,可以使用异步加载。但存在BUG:单显示的条目很多。ListView需要往下拉的时候。图片不能显示,但是使用1的方法却能全部显示出来

参考资料:http://hulefei29.iteye.com/blog/616262

 

例子:

1、定义主界面,在界面里面添加一个ListView控件

main.xml

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="wrap_content" 
5.    android:layout_height="fill_parent"> 
6.<TextView    
7.    android:id="@+id/indexTitle" 
8.    android:layout_width="fill_parent"   
9.    android:gravity="center" 
10.    android:layout_height="wrap_content" 
11.    android:text="使用ListView显示图片"/> 
12.<ListView   
13.    android:id="@+id/searchList"         
14.    android:layout_width="fill_parent"   
15.    android:layout_height="wrap_content" 
16.    android:choiceMode="singleChoice" />           
17.</LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent">
<TextView 
 android:id="@+id/indexTitle"
    android:layout_width="fill_parent"
    android:gravity="center"
    android:layout_height="wrap_content"
    android:text="使用ListView显示图片"/>
<ListView
 android:id="@+id/searchList"      
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:choiceMode="singleChoice" />     
</LinearLayout>

 

2、定义Item页面

search_list.xml

Xml代码 
1.<?xml version="1.0" encoding="utf-8"?> 
2.<LinearLayout 
3.xmlns:android="http://schemas.android.com/apk/res/android
4.android:layout_width="wrap_content" 
5.android:layout_height="wrap_content"> 
6. 
7.    <ImageView android:id="@+id/stationImg" 
8.        android:layout_width="wrap_content" 
9.        android:layout_height="wrap_content"   
10.        android:minWidth="80px" 
11.        android:maxWidth="80px" 
12.        android:minHeight="45px" 
13.        android:maxHeight="45px" 
14.        android:scaleType="fitXY"   
15.        android:src="@drawable/icon"      
16.        android:layout_margin="5px"/> 
17.    <LinearLayout android:orientation="vertical" 
18.        android:layout_width="wrap_content" 
19.        android:layout_height="wrap_content"> 
20.          
21.        <TextView android:id="@+id/stationTitle" 
22.            android:layout_width="wrap_content" 
23.            android:layout_height="wrap_content" 
24.            android:textColor="#FFFFFFFF" 
25.            android:textSize="22px"   
26.            /> 
27.          
28.        <TextView   
29.            android:id="@+id/stationInfo" 
30.            android:layout_width="wrap_content" 
31.            android:layout_height="wrap_content" 
32.            android:textColor="#FFFFFFFF" 
33.            android:textSize="13px" /> 
34.    </LinearLayout> 
35. 
36.</LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

    <ImageView android:id="@+id/stationImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="80px"
        android:maxWidth="80px"
        android:minHeight="45px"
        android:maxHeight="45px"
        android:scaleType="fitXY"
        android:src="@drawable/icon"   
        android:layout_margin="5px"/>
    <LinearLayout android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
       
        <TextView android:id="@+id/stationTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFFFF"
            android:textSize="22px"
            />
       
        <TextView
         android:id="@+id/stationInfo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFFFFFFF"
            android:textSize="13px" />
    </LinearLayout>

</LinearLayout>
 

 

三、定义MainActivity

MainActivity.java

Java代码 
1.package lee.listviewimage;  
2. 
3.import java.util.ArrayList;  
4.import java.util.HashMap;  
5.import java.util.List;  
6.import java.util.Map;  
7.import lee.listviewimage.R;  
8.import android.app.Activity;  
9.import android.os.Bundle;  
10.import android.widget.ListView;  
11. 
12. 
13.public class MainActivity extends Activity {  
14.//  private List<Map<String, Object>> generateData(List<XXXX> xxxxs) {  
15.//        List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();  
16.//        for (Iterator<XXXX> iterator = xxxxs.iterator(); iterator  
17.//                .hasNext();) {  
18.//            XXXX xxxx= (XXXX) iterator.next();  
19.//            Map<String, Object> resMap = new HashMap<String, Object>();  
20.//            resMap.put("title", xxxx.getTitle());  
21.//            resMap.put("info", xxxx.getInfo());  
22.//            resMap.put("img", xxxx.getImageUrl());  
23.//            resList.add(resMap);  
24.//        }  
25.//        return resList;  
26.//    }  
27. 
28.    ListView view;  
29.    List<Map<String, Object>> resList;   
30.    @Override 
31.    public void onCreate(Bundle savedInstanceState) {  
32.        super.onCreate(savedInstanceState);  
33.        setContentView(R.layout.main);  
34.        view = (ListView) findViewById(R.id.searchList);  
35.        resList = new ArrayList<Map<String, Object>>();  
36. 
37.        Map<String, Object> resMap = new HashMap<String, Object>();  
38.        resMap.put("title", "title111");  
39.        resMap.put("info", "111111");  
40.        resMap.put("img", "http://tb.himg.baidu.com/sys/portrait/item/d71e5a30323837797979d300");  
41.        resList.add(resMap);  
42.          
43.        resMap = new HashMap<String, Object>();  
44.        resMap.put("title", "title222");  
45.        resMap.put("info", "222222");  
46.        resMap.put("img", "http://img.baidu.com/img/post-jg.gif");  
47.        resList.add(resMap);  
48.          
49. 
50.        SearchAdapter adapter = new SearchAdapter(  
51.            this,resList, R.layout.search_list,   
52.            new String[] {"title", "info", "img" },   
53.            new int[] {R.id.stationTitle, R.id.stationInfo,R.id.stationImg  
54.        });  
55. 
56.        view.setAdapter(adapter);  
57.    }      
58.} 
package lee.listviewimage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lee.listviewimage.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;


public class MainActivity extends Activity {
// private List<Map<String, Object>> generateData(List<XXXX> xxxxs) {
//        List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
//        for (Iterator<XXXX> iterator = xxxxs.iterator(); iterator
//                .hasNext();) {
//            XXXX xxxx= (XXXX) iterator.next();
//            Map<String, Object> resMap = new HashMap<String, Object>();
//            resMap.put("title", xxxx.getTitle());
//            resMap.put("info", xxxx.getInfo());
//            resMap.put("img", xxxx.getImageUrl());
//            resList.add(resMap);
//        }
//        return resList;
//    }

    ListView view;
    List<Map<String, Object>> resList;
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        view = (ListView) findViewById(R.id.searchList);
        resList = new ArrayList<Map<String, Object>>();

        Map<String, Object> resMap = new HashMap<String, Object>();
        resMap.put("title", "title111");
        resMap.put("info", "111111");
        resMap.put("img", "http://tb.himg.baidu.com/sys/portrait/item/d71e5a30323837797979d300");
        resList.add(resMap);
       
        resMap = new HashMap<String, Object>();
        resMap.put("title", "title222");
        resMap.put("info", "222222");
        resMap.put("img", "http://img.baidu.com/img/post-jg.gif");
        resList.add(resMap);
       

        SearchAdapter adapter = new SearchAdapter(
      this,resList, R.layout.search_list,
      new String[] {"title", "info", "img" },
      new int[] {R.id.stationTitle, R.id.stationInfo,R.id.stationImg
        });

        view.setAdapter(adapter);
 }   
}

四、定义通过图片url返回图片Bitmap的工具类"(如果不需要异步,直接调用这个方法)

WebImageBuilder.java

Java代码 
1.package lee.listviewimage;  
2. 
3.import java.io.IOException;  
4.import java.io.InputStream;  
5.import java.net.HttpURLConnection;  
6.import java.net.MalformedURLException;  
7.import java.net.URL;  
8. 
9.import android.graphics.Bitmap;  
10.import android.graphics.BitmapFactory;  
11. 
12.public class WebImageBuilder {  
13. 
14.    /** 
15.     * 通过图片url返回图片Bitmap 
16.     * @param url 
17.     * @return 
18.     */ 
19.    public static Bitmap returnBitMap(String path) {  
20.        URL url = null;  
21.        Bitmap bitmap = null;  
22.        try {  
23.            url = new URL(path);  
24.        } catch (MalformedURLException e) {  
25.            e.printStackTrace();  
26.        }  
27.        try {  
28.            HttpURLConnection conn = (HttpURLConnection) url.openConnection();//利用HttpURLConnection对象,我们可以从网络中获取网页数据.  
29.            conn.setDoInput(true);  
30.            conn.connect();  
31.            InputStream is = conn.getInputStream(); //得到网络返回的输入流  
32.            bitmap = BitmapFactory.decodeStream(is);  
33.            is.close();  
34.        } catch (IOException e) {  
35.            e.printStackTrace();  
36.        }  
37.        return bitmap;  
38.    }  
39.} 
package lee.listviewimage;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class WebImageBuilder {

 /**
  * 通过图片url返回图片Bitmap
  * @param url
  * @return
  */
 public static Bitmap returnBitMap(String path) {
  URL url = null;
  Bitmap bitmap = null;
  try {
   url = new URL(path);
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }
  try {
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();//利用HttpURLConnection对象,我们可以从网络中获取网页数据.
   conn.setDoInput(true);
   conn.connect();
   InputStream is = conn.getInputStream(); //得到网络返回的输入流
   bitmap = BitmapFactory.decodeStream(is);
   is.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return bitmap;
 }
}
 

五、定义异步加载图片的工具类

AsyncImageLoader.java

Java代码 
1.package lee.listviewimage;  
2.import java.lang.ref.SoftReference;  
3.import java.net.URL;  
4.import java.util.HashMap;  
5.import java.util.Map;  
6.import android.graphics.drawable.Drawable;  
7.import android.os.Handler;  
8.import android.os.Message;  
9. 
10.public class AsyncImageLoader {  
11.    private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();  
12. 
13.    public Drawable loadDrawable(final String imageUrl,final ImageCallback callback) {  
14. 
15.        if (imageCache.containsKey(imageUrl)) {  
16.            SoftReference<Drawable> softReference = imageCache.get(imageUrl);  
17.            if (softReference.get() != null) {  
18.                return softReference.get();  
19.            }  
20.        }  
21.        final Handler handler = new Handler() {  
22.            @Override 
23.            public void handleMessage(Message msg) {  
24.                callback.imageLoaded((Drawable) msg.obj, imageUrl);  
25.            }  
26.        };  
27.        //load data  
28.        new Thread() {  
29.            public void run() {  
30.                Drawable drawable = loadImageFromUrl(imageUrl);  
31.                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));  
32.                handler.sendMessage(handler.obtainMessage(0, drawable));  
33.            };  
34.        }.start();  
35.          
36.        return null;  
37.    }  
38. 
39.    protected Drawable loadImageFromUrl(String imageUrl) {  
40.        try {  
41.            return Drawable.createFromStream(new URL(imageUrl).openStream(),  
42.                    "src");  
43.        } catch (Exception e) {  
44.            throw new RuntimeException(e);  
45.        }  
46.    }  
47. 
48.    //call back interface  
49.    public interface ImageCallback {  
50.        public void imageLoaded(Drawable imageDrawable, String imageUrl);  
51.    }  
52.      
53.} 
package lee.listviewimage;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

public class AsyncImageLoader {
    private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();

    public Drawable loadDrawable(final String imageUrl,final ImageCallback callback) {

     if (imageCache.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            if (softReference.get() != null) {
                return softReference.get();
            }
        }
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                callback.imageLoaded((Drawable) msg.obj, imageUrl);
            }
        };
        //load data
        new Thread() {
            public void run() {
                Drawable drawable = loadImageFromUrl(imageUrl);
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                handler.sendMessage(handler.obtainMessage(0, drawable));
            };
        }.start();
       
        return null;
    }

    protected Drawable loadImageFromUrl(String imageUrl) {
        try {
            return Drawable.createFromStream(new URL(imageUrl).openStream(),
                    "src");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //call back interface
    public interface ImageCallback {
        public void imageLoaded(Drawable imageDrawable, String imageUrl);
    }
   
}
 

六、定义异步加载图片的方法

PS:原文章说只有 public SearchAdapter构造方法和 public void setViewImage(final ImageView v, String url)有用,其他都是源代码。理论上可以去掉不写,但去掉后确不能正常显示图片,有全部都是同一张图片,或者只显示1条数据,但去掉的方法却可以不在异步的显示图片中测试成功。(看第七点)

SearchAdapter.java

Java代码 
1.package lee.listviewimage;  
2.import java.util.HashMap;  
3.import java.util.List;  
4.import java.util.Map;  
5.import android.content.Context;  
6.import android.graphics.Bitmap;  
7.import android.graphics.drawable.Drawable;  
8.import android.view.LayoutInflater;  
9.import android.view.View;  
10.import android.view.ViewGroup;  
11.import android.widget.Checkable;  
12.import android.widget.ImageView;  
13.import android.widget.SimpleAdapter;  
14.import android.widget.TextView;  
15. 
16.public class SearchAdapter extends SimpleAdapter {  
17.      
18.    private AsyncImageLoader imageLoader = new AsyncImageLoader();  
19.    private Map<Integer, View> viewMap = new HashMap<Integer, View>();  
20.    private ViewBinder mViewBinder;  
21.    private List<? extends Map<String, ?>> mData;       //List列表存放的数据  
22.    private int mResource;                          //绑定的页面 ,例如:R.layout.search_item,   
23.    private LayoutInflater mInflater;  
24.    private String[] mFrom;                         //绑定控件对应的数组里面的值名称  
25.    private int[] mTo;                              //绑定控件的ID     
26.      
27.    //构造器  
28.    public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {  
29.        super(context, data, resource, from, to);  
30.        mData = data;  
31.        mResource = resource;  
32.        mFrom = from;  
33.        mTo = to;  
34.        // 布局泵(LayoutInflater)根据XML布局文件来绘制视图(View)对象。这个类无法直接创建实例,要通过context对象的getLayoutInflater()或getSystemService(String)方法来获得实例,这样获得的布局泵实例符合设备的环境配置。  
35.        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
36.    }  
37. 
38. 
39.        /* 
40.        SimpleAdapter基类显示每个Item都是通过这个方法生成的 
41.        在getView(int position, View convertView, ViewGroup parent)中又调用了SimpleAdapter的私有方法createViewFromResource 
42.        来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from 和int[] to进行了组装    
43.         */ 
44.    public View getView(int position, View convertView, ViewGroup parent) {  
45.        return createViewFromResource(position, convertView, parent, mResource);    //调用下面方法  
46.    }  
47. 
48.   
49.    //在createViewFromResource方法中又有一个bindView(position, v)方法对item中的各个View进行了组装,bindView(position, v)  
50.    private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {  
51.        View rowView = this.viewMap.get(position);  
52.          
53.        if (rowView == null) {  
54.            rowView = mInflater.inflate(resource, null);  
55. 
56.            final int[] to = mTo;  
57.            final int count = to.length;  
58.            final View[] holder = new View[count];  
59. 
60.            for (int i = 0; i < count; i++) {  
61. 
62. 
63.                holder[i] = rowView.findViewById(to[i]);  
64.            }  
65.            rowView.setTag(holder);  
66.            bindView(position, rowView);    //调用下面方法对Item中的  
67.            viewMap.put(position, rowView);  
68.        }  
69.        return rowView;  
70.    }  
71.      
72.    //对ViewImage进行组装的代码了“else if (v instanceof ImageView)”  
73.    @SuppressWarnings("unchecked")  
74.    private void bindView(int position, View view) {  
75.        final Map dataSet = mData.get(position);  
76.        if (dataSet == null) {  
77.            return;  
78.        }  
79. 
80.        final ViewBinder binder = mViewBinder;  
81.        final View[] holder = (View[]) view.getTag();  
82.        final String[] from = mFrom;  
83.        final int[] to = mTo;  
84.        final int count = to.length;  
85. 
86.        for (int i = 0; i < count; i++) {  
87.            final View v = holder[i];  
88.            if (v != null) {  
89.                final Object data = dataSet.get(from[i]);  
90.                String urlText = null;  
91. 
92.                if (data == null) {  
93.                    urlText = "";  
94.                } else {  
95.                    urlText = data.toString();  
96.                }  
97. 
98.                boolean bound = false;  
99.                if (binder != null) {  
100.                    bound = binder.setViewValue(v, data, urlText);  
101.                }  
102. 
103.                if (!bound) {  
104.                    if (v instanceof Checkable) {  
105.                        if (data instanceof Boolean) {  
106.                            ((Checkable) v).setChecked((Boolean) data);  
107.                        } else {  
108.                            throw new IllegalStateException(v.getClass()  
109.                                    .getName()  
110.                                    + " should be bound to a Boolean, not a " 
111.                                    + data.getClass());  
112.                        }  
113.                    } else if (v instanceof TextView) {  
114.                        setViewText((TextView) v, urlText);  
115.                    } else if (v instanceof ImageView) {  
116.                        if (data instanceof Integer) {  
117.                            setViewImage((ImageView) v, (Integer) data);  
118.                        } else {  
119.                            setViewImage((ImageView) v, urlText);  
120.                        }  
121.                    } else {  
122.                        throw new IllegalStateException(  
123.                                v.getClass().getName()  
124.                                        + " is not a " 
125.                                        + " view that can be bounds by this SimpleAdapter");  
126.                    }  
127.                }  
128.            }  
129.        }  
130.    }  
131. 
132. 
133.     public void setViewImage(ImageView v, int value) {  
134.         v.setImageResource(value);  
135.     }  
136. 
137.     public void setViewImage(final ImageView v, String url) {  
138.         //如果只是单纯的把图片显示,而不进行缓存。直接用下面的方法拿到URL的Bitmap就行显示就OK  
139.//       Bitmap bitmap = WebImageBuilder.returnBitMap(url);  
140.//       ((ImageView) v).setImageBitmap(bitmap);  
141. 
142.         imageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() {  
143.             public void imageLoaded(Drawable imageDrawable, String imageUrl) {  
144.                 if(imageDrawable!=null && imageDrawable.getIntrinsicWidth()>0 ) {  
145.                     v.setImageDrawable(imageDrawable);  
146.                 }  
147.             }  
148.         });  
149.     }  
150. 
151. }  
package lee.listviewimage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class SearchAdapter extends SimpleAdapter {
   
    private AsyncImageLoader imageLoader = new AsyncImageLoader();
    private Map<Integer, View> viewMap = new HashMap<Integer, View>();
    private ViewBinder mViewBinder;
    private List<? extends Map<String, ?>> mData;  //List列表存放的数据
    private int mResource;       //绑定的页面 ,例如:R.layout.search_item,
    private LayoutInflater mInflater;
    private String[] mFrom;       //绑定控件对应的数组里面的值名称
    private int[] mTo;        //绑定控件的ID 
   
    //构造器
    public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        mData = data;
        mResource = resource;
        mFrom = from;
        mTo = to;
        // 布局泵(LayoutInflater)根据XML布局文件来绘制视图(View)对象。这个类无法直接创建实例,要通过context对象的getLayoutInflater()或getSystemService(String)方法来获得实例,这样获得的布局泵实例符合设备的环境配置。
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


     /*
      SimpleAdapter基类显示每个Item都是通过这个方法生成的
     在getView(int position, View convertView, ViewGroup parent)中又调用了SimpleAdapter的私有方法createViewFromResource
     来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from 和int[] to进行了组装  
      */
    public View getView(int position, View convertView, ViewGroup parent) {
        return createViewFromResource(position, convertView, parent, mResource); //调用下面方法
    }

 
    //在createViewFromResource方法中又有一个bindView(position, v)方法对item中的各个View进行了组装,bindView(position, v)
    private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
        View rowView = this.viewMap.get(position);
       
        if (rowView == null) {
            rowView = mInflater.inflate(resource, null);

            final int[] to = mTo;
            final int count = to.length;
            final View[] holder = new View[count];

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


                holder[i] = rowView.findViewById(to[i]);
            }
            rowView.setTag(holder);
            bindView(position, rowView); //调用下面方法对Item中的
            viewMap.put(position, rowView);
        }
        return rowView;
    }
   
    //对ViewImage进行组装的代码了“else if (v instanceof ImageView)”
    @SuppressWarnings("unchecked")
    private void bindView(int position, View view) {
        final Map dataSet = mData.get(position);
        if (dataSet == null) {
            return;
        }

        final ViewBinder binder = mViewBinder;
        final View[] holder = (View[]) view.getTag();
        final String[] from = mFrom;
        final int[] to = mTo;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View v = holder[i];
            if (v != null) {
                final Object data = dataSet.get(from[i]);
                String urlText = null;

                if (data == null) {
                    urlText = "";
                } else {
                    urlText = data.toString();
                }

                boolean bound = false;
                if (binder != null) {
                    bound = binder.setViewValue(v, data, urlText);
                }

                if (!bound) {
                    if (v instanceof Checkable) {
                        if (data instanceof Boolean) {
                            ((Checkable) v).setChecked((Boolean) data);
                        } else {
                            throw new IllegalStateException(v.getClass()
                                    .getName()
                                    + " should be bound to a Boolean, not a "
                                    + data.getClass());
                        }
                    } else if (v instanceof TextView) {
                        setViewText((TextView) v, urlText);
                    } else if (v instanceof ImageView) {
                        if (data instanceof Integer) {
                            setViewImage((ImageView) v, (Integer) data);
                        } else {
                            setViewImage((ImageView) v, urlText);
                        }
                    } else {
                        throw new IllegalStateException(
                                v.getClass().getName()
                                        + " is not a "
                                        + " view that can be bounds by this SimpleAdapter");
                    }
                }
            }
        }
    }


     public void setViewImage(ImageView v, int value) {
         v.setImageResource(value);
     }

     public void setViewImage(final ImageView v, String url) {
      //如果只是单纯的把图片显示,而不进行缓存。直接用下面的方法拿到URL的Bitmap就行显示就OK
//       Bitmap bitmap = WebImageBuilder.returnBitMap(url);
//       ((ImageView) v).setImageBitmap(bitmap);

         imageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() {
             public void imageLoaded(Drawable imageDrawable, String imageUrl) {
                 if(imageDrawable!=null && imageDrawable.getIntrinsicWidth()>0 ) {
                     v.setImageDrawable(imageDrawable);
                 }
             }
         });
     }

 }
 

 

七、如果不需要异步加载,可以修改上面的SearchAdapter方法

(1):可以在上面的基础上修改public void setViewImage(final ImageView v, String url)方法

Java代码 
1.public void setViewImage(final ImageView v, String url) {  
2.    Bitmap bitmap = WebImageBuilder.returnBitMap(url);  
3.   ((ImageView) v).setImageBitmap(bitmap);  
4.} 
     public void setViewImage(final ImageView v, String url) {
         Bitmap bitmap = WebImageBuilder.returnBitMap(url);
        ((ImageView) v).setImageBitmap(bitmap);
     }

 

 

(2)可以只剩下public SearchAdapter构造方法和 public void setViewImage(final ImageView v, String url)2个方法,其他方法都去掉

Java代码 
1.package lee.listviewimage;  
2.import java.util.List;  
3.import java.util.Map;  
4.import android.content.Context;  
5.import android.graphics.Bitmap;  
6.import android.widget.ImageView;  
7.import android.widget.SimpleAdapter;  
8. 
9.public class SearchAdapter extends SimpleAdapter {  
10.      
11.    //构造器  
12.    public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {  
13.        super(context, data, resource, from, to);  
14.    }  
15. 
16.    public void setViewImage(final ImageView v, String url) {  
17.       Bitmap bitmap = WebImageBuilder.returnBitMap(url);  
18.       ((ImageView) v).setImageBitmap(bitmap);  
19. 
20.     }  
21. }  
package lee.listviewimage;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import android.widget.SimpleAdapter;

public class SearchAdapter extends SimpleAdapter {
   
    //构造器
    public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
    }

    public void setViewImage(final ImageView v, String url) {
       Bitmap bitmap = WebImageBuilder.returnBitMap(url);
       ((ImageView) v).setImageBitmap(bitmap);

     }
 }
如果只是打开单个图片可以使用这个方法

 

PS:异步方法应该也可以精简到上面那样只剩下2个方法,但测试不成功。,有待修改

 

 

问题1:

今天测试的时候又发现了问题:单图片的地址错误或者无法连接时,使用异步的方法虽然能正常显示其他图片,但单连接错误的图片超时后。系统会自动跳出提示错误信息。原来源文件没有处理这种情况,所以需要对异步的AsyncImageLoader.java文件的loadImageFromUrl方法进行修改

Java代码 
1.//定义方法链接URL获取输入流,然后转换成Drawable  
2.protected Drawable loadImageFromUrl(String imageUrl) {  
3.    try {  
4.        return Drawable.createFromStream(new URL(imageUrl).openStream(),"src");//当URL不正确或者链接不上。new URL(imageUrl).openStream()会抛错。所以需要在抛错的时候返回NULL。  
5.    } catch (Exception e) {  
6. 
7.      //  throw new RuntimeException(e);  
8.     return Drawable.createFromStream(null,"src");  
9.           
10.    }  
11.}: 
    //定义方法链接URL获取输入流,然后转换成Drawable
    protected Drawable loadImageFromUrl(String imageUrl) {
        try {
            return Drawable.createFromStream(new URL(imageUrl).openStream(),"src");//当URL不正确或者链接不上。new URL(imageUrl).openStream()会抛错。所以需要在抛错的时候返回NULL。
        } catch (Exception e) {

          //  throw new RuntimeException(e);
         return Drawable.createFromStream(null,"src");
         
        }
    }:

问题2:

单显示的条目很多。需要Listview往下拉,这样当翻页的图片如果是第一页相同的图片。会出现不能显示的问题,这样就导致了没有缓冲的同能。

 

原因:

主要是因为

Java代码 
1.if (imageCache.containsKey(imageUrl)) {  
2.    SoftReference<Drawable> softReference = imageCache.get(imageUrl);  
3.    if (softReference.get() != null) {  
4.        return softReference.get();  
5.    }  
6.} 
         if (imageCache.containsKey(imageUrl)) {
             SoftReference<Drawable> softReference = imageCache.get(imageUrl);
             if (softReference.get() != null) {
                 return softReference.get();
             }
         }
 这段代码没有起作用。因为他只是直接返回softReference.get();结果。并没有对他进行显示

 

 


解决:

把上面的代码放到线程里面去。同时优化了一下。加了线程池管理线程启动的个数

Java代码 
1.try {     
2.    threadPool.execute(new Runnable() {     
3. 
4.        @Override    
5.        public void run() {     
6.              
7.      if (imageCache.containsKey(imageUrl)) {       //检查缓冲imageCache是否存在对应的KEY  
8.          SoftReference<Drawable> softReference = imageCache.get(imageUrl);   //存在就获取对应的值  
9.          Log.i("abc", "1:"+softReference.get().toString());  
10.          if (softReference.get() != null) {      
11.              Log.i("abc", "2:"+softReference.get().toString());  
12.              Message message = handler.obtainMessage(0, softReference.get());    
13.              handler.sendMessage(message);  
14.              
15.          }  
16.      }else{  
17.              
18.             Drawable drawable = loadImageFromUrl(imageUrl);            //使用下面的方法获取Drawable  
19.             imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); //把图片放到HasMap中  
20.             Log.i("abc", "0:"+drawable);  
21.             Message message = handler.obtainMessage(0, drawable);    
22.             handler.sendMessage(message);  
23.       }     
24.      }  
25.    });     
26.} catch (Exception e) {     
27.    e.printStackTrace();     
28.}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值