现在的位置: 首页 > 综合 > 正文

如何实现ListView异步加载图片

2014年03月16日 ⁄ 综合 ⁄ 共 7782字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.