ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法可以带来较好的用户体验。下面就给大家说明如何让实现该方法:
Java代码
1 package cn.wangmeng.test;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 importjava.lang.ref.SoftReference;
6 importjava.net.MalformedURLException;
7 import java.net.URL;
8 import java.util.HashMap;
9
10 importandroid.graphics.drawable.Drawable;
11 import android.os.Handler;
12 import android.os.Message;
13
14 public class AsyncImageLoader {
15
16 private HashMap<String, SoftReference<Drawable>>imageCache;
17
18 public AsyncImageLoader() {
19 imageCache = new HashMap<String,SoftReference<Drawable>>();
20 }
21
22 public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
23 if(imageCache.containsKey(imageUrl)) {
24 SoftReference<Drawable>softReference = imageCache.get(imageUrl);
25 Drawable drawable =softReference.get();
26 if (drawable != null) {
27 return drawable;
28 }
29 }
30 final Handler handler = new Handler() {
31 public void handleMessage(Messagemessage) {
32 imageCallback.imageLoaded((Drawable)message.obj, imageUrl);
33 }
34 };
35 new Thread() {
36 @Override
37 public void run() {
38 Drawable drawable =loadImageFromUrl(imageUrl);
39 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
40 Message message =handler.obtainMessage(0, drawable);
41 handler.sendMessage(message);
42 }
43 }.start();
44 return null;
45 }
46
47 public static DrawableloadImageFromUrl(String url) {
48 URLm;
49 InputStream i = null;
50 try {
51 m = new URL(url);
52 i =(InputStream) m.getContent();
53 } catch (MalformedURLException e1){
54 e1.printStackTrace();
55 } catch (IOException e) {
56 e.printStackTrace();
57 }
58 Drawabled = Drawable.createFromStream(i, "src");
59 return d;
60 }
61
62 public interface ImageCallback {
63 public void imageLoaded(DrawableimageDrawable, String imageUrl);
64 }
65
66 }
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
几个辅助类文件:
Java代码
67 package cn.wangmeng.test;
68
69 public class ImageAndText {
70 private String imageUrl;
71 private String text;
72
73 public ImageAndText(String imageUrl, String text) {
74 this.imageUrl = imageUrl;
75 this.text = text;
76 }
77 public String getImageUrl() {
78 return imageUrl;
79 }
80 public String getText() {
81 return text;
82 }
83 }
Java代码
84 package cn.wangmeng.test;
85
86 import android.view.View;
87 importandroid.widget.ImageView;
88 importandroid.widget.TextView;
89
90 public class ViewCache {
91
92 private View baseView;
93 private TextView textView;
94 private ImageView imageView;
95
96 public ViewCache(View baseView) {
97 this.baseView = baseView;
98 }
99
100 public TextView getTextView() {
101 if (textView == null) {
102 textView = (TextView)baseView.findViewById(R.id.text);
103 }
104 return textView;
105 }
106
107 public ImageView getImageView() {
108 if (imageView == null) {
109 imageView = (ImageView)baseView.findViewById(R.id.image);
110 }
111 return imageView;
112 }
113
114 }
ViewCache是辅助获取adapter的子元素布局
Java代码
115 package cn.wangmeng.test;
116
117 import java.util.List;
118
119 importcn.wangmeng.test.AsyncImageLoader.ImageCallback;
120
121 import android.app.Activity;
122 importandroid.graphics.drawable.Drawable;
123 import android.view.LayoutInflater;
124 import android.view.View;
125 import android.view.ViewGroup;
126 importandroid.widget.ArrayAdapter;
127 importandroid.widget.ImageView;
128 importandroid.widget.ListView;
129 importandroid.widget.TextView;
130
131 public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
132
133 private ListView listView;
134 private AsyncImageLoader asyncImageLoader;
135
136 public ImageAndTextListAdapter(Activity activity,List<ImageAndText> imageAndTexts, ListView listView) {
137 super(activity, 0, imageAndTexts);
138 this.listView = listView;
139 asyncImageLoader = new AsyncImageLoader();
140 }
141
142 public View getView(int position, View convertView,ViewGroup parent) {
143 Activity activity = (Activity)getContext();
144
145 // Inflate the views fromXML
146 ViewrowView = convertView;
147 ViewCacheviewCache;
148 if (rowView == null) {
149 LayoutInflater inflater = activity.getLayoutInflater();
150 rowView =inflater.inflate(R.layout.image_and_text_row, null);
151 viewCache = new ViewCache(rowView);
152 rowView.setTag(viewCache);
153 } else {
154 viewCache = (ViewCache)rowView.getTag();
155 }
156 ImageAndText imageAndText =getItem(position);
157
158 // Load the image and setit on the ImageView
159 StringimageUrl = imageAndText.getImageUrl();
160 ImageViewimageView = viewCache.getImageView();
161 imageView.setTag(imageUrl);
162 DrawablecachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
163 public void imageLoaded(DrawableimageDrawable, String imageUrl) {
164 ImageView imageViewByTag =(ImageView) listView.findViewWithTag(imageUrl);
165 if (imageViewByTag != null) {
166 imageViewByTag.setImageDrawable(imageDrawable);
167 }
168 }
169 });
170 if (cachedImage == null) {
171 imageView.setImageResource(R.drawable.default_image);
172 }else{
173 imageView.setImageDrawable(cachedImage);
174 }
175 // Set the text on theTextView
176 TextViewtextView = viewCache.getTextView();
177 textView.setText(imageAndText.getText());
178
179 return rowView;
180 }
181
182 }
ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。
最后贴出布局文件:
Xml代码
183 <?xml version="1.0" encoding="utf-8"?>
184 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
185 android:orientation="horizontal"
186 android:layout_width="fill_parent"
187 android:layout_height="wrap_content">
188
189 <ImageView android:id="@+id/image"
190 android:layout_width="wrap_content"
191 android:layout_height="wrap_content"
192 />
193
194 <TextView android:id="@+id/text"
195 android:layout_width="wrap_content"
196 android:layout_height="wrap_content"/>
197
198 </LinearLayout>
欢迎访问: www.orietech.com
英文博客: orietech.wordpress.com