[转载]Android实现ListView异步加载图片
原文分享地址:http://apps.hi.baidu.com/share/detail/34554080
ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,不用让用户等待下去,下面就说实现方法,先贴上主方法的代码:
packagecn.wangmeng.test;importJava.io.IOException;importjava.io.InputStream;importjava.lang.ref.SoftReference;importjava.NET.MalformedURLException;importjava.net.URL;importjava.util.HashMap;importAndroid.graphics.drawable.Drawable;importandroid.os.Handler;importandroid.os.Message;public classAsyncImageLoader { privateHashMap < String, SoftReference < Drawable >>imageCache; publicAsyncImageLoader() { imageCache= newHashMap < String, SoftReference < Drawable >> (); } publicDrawable loadDrawable( finalString imageUrl,finalImageCallback imageCallback) { if(imageCache.containsKey(imageUrl)) { SoftReference < Drawable >softReference=imageCache.get(imageUrl); Drawable drawable=softReference.get(); if(drawable!= null ) { returndrawable; } } finalHandler handler= newHandler() { public voidhandleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; newThread() { @Override public voidrun() { Drawable drawable=loadImageFromUrl(imageUrl); imageCache.put(imageUrl,newSoftReference < Drawable > (drawable)); Message message=handler.obtainMessage( 0 , drawable); handler.sendMessage(message); } }.start(); return null ; } public staticDrawable loadImageFromUrl(String url) { URL m; InputStream i= null ; try{ m= newURL(url); i=(InputStream) m.getContent(); }catch(MalformedURLException e1) { e1.printStackTrace(); }catch(IOException e) { e.printStackTrace(); } Drawable d=Drawable.createFromStream(i," src " ); returnd; } public interfaceImageCallback { public voidimageLoaded(Drawable imageDrawable, String imageUrl); }} 以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
ViewCache是辅助获取adapter的子元素布局
packagecn.wangmeng.test;importjava.util.List;importcn.wangmeng.test.AsyncImageLoader.ImageCallback;importandroid.app.Activity;importandroid.graphics.drawable.Drawable;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.ArrayAdapter;importandroid.widget.ImageView;importandroid.widget.ListView;importandroid.widget.TextView;public classImageAndTextListAdapterextendsArrayAdapter < ImageAndText >{ privateListView listView; privateAsyncImageLoader asyncImageLoader; publicImageAndTextListAdapter(Activity activity, List < ImageAndText >imageAndTexts, ListView listView) { super (activity,0 , imageAndTexts); this .listView=listView; asyncImageLoader= newAsyncImageLoader(); } publicView getView( intposition, 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= newViewCache(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,newImageCallback() { public voidimageLoaded(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()); returnrowView; }} ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。
页:
[1]