`
helpbs
  • 浏览: 1162088 次
文章分类
社区版块
存档分类
最新评论

list 异步加载图片

 
阅读更多

ListView是一种可以显示一系列项目并能进行滚动显示的View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很好滚动流畅是做不到的

所以这里就需要把这些信息利用多线程实现异步加载

实现这样功能的类

  1. publicclassAsyncImageLoader{
  2. privateHashMap<String,SoftReference<Drawable>>imageCache;
  3. publicAsyncImageLoader(){
  4. imageCache=newHashMap<String,SoftReference<Drawable>>();
  5. }
  6. publicDrawableloadDrawable(finalStringimageUrl,finalImageCallbackimageCallback){
  7. if(imageCache.containsKey(imageUrl)){
  8. SoftReference<Drawable>softReference=imageCache.get(imageUrl);
  9. Drawabledrawable=softReference.get();
  10. if(drawable!=null){
  11. returndrawable;
  12. }
  13. }
  14. finalHandlerhandler=newHandler(){
  15. @Override
  16. publicvoidhandleMessage(Messagemessage){
  17. imageCallback.imageLoaded((Drawable)message.obj,imageUrl);
  18. }
  19. };
  20. newThread(){
  21. @Override
  22. publicvoidrun(){
  23. Drawabledrawable=loadImageFromUrl(imageUrl);
  24. imageCache.put(imageUrl,newSoftReference<Drawable>(drawable));
  25. Messagemessage=handler.obtainMessage(0,drawable);
  26. handler.sendMessage(message);
  27. }
  28. }.start();
  29. returnnull;
  30. }
  31. publicstaticDrawableloadImageFromUrl(Stringurl){
  32. //...
  33. }
  34. publicinterfaceImageCallback{
  35. publicvoidimageLoaded(DrawableimageDrawable,StringimageUrl);
  36. }
  37. }

注意这里使用了SoftReference来缓存图片,允许GC在需要的时候可以对缓存中的图片进行清理。它这样工作:

·调用loadDrawable(ImageUrl, imageCallback),传入一个匿名实现的ImageCallback接口

·如果图片在缓存中不存在的话,图片将从单一的线程中下载并在下载结束时通过ImageCallback回调

·如果图片确实存在于缓存中,就会马上返回,不会回调ImageCallback

然后我们还可以根据09google I/0开发者大会提到的方式来继续优化Adapter 使用ViewHolder来减少一些比较费时的操作,譬如inflate XML 和 findViewById()等操作

  1. publicclassImageAndTextListAdapterextendsArrayAdapter<ImageAndText>{
  2. privateListViewlistView;
  3. privateAsyncImageLoaderasyncImageLoader;
  4. publicImageAndTextListAdapter(Activityactivity,List<ImageAndText>imageAndTexts,ListViewlistView){
  5. super(activity,0,imageAndTexts);
  6. this.listView=listView;
  7. asyncImageLoader=newAsyncImageLoader();
  8. }
  9. @Override
  10. publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
  11. Activityactivity=(Activity)getContext();
  12. //InflatetheviewsfromXML
  13. ViewrowView=convertView;
  14. ViewCacheviewCache;
  15. if(rowView==null){
  16. LayoutInflaterinflater=activity.getLayoutInflater();
  17. rowView=inflater.inflate(R.layout.image_and_text_row,null);
  18. viewCache=newViewCache(rowView);
  19. rowView.setTag(viewCache);
  20. }else{
  21. viewCache=(ViewCache)rowView.getTag();
  22. }
  23. ImageAndTextimageAndText=getItem(position);
  24. //LoadtheimageandsetitontheImageView
  25. StringimageUrl=imageAndText.getImageUrl();
  26. ImageViewimageView=viewCache.getImageView();
  27. imageView.setTag(imageUrl);
  28. DrawablecachedImage=asyncImageLoader.loadDrawable(imageUrl,newImageCallback(){
  29. publicvoidimageLoaded(DrawableimageDrawable,StringimageUrl){
  30. ImageViewimageViewByTag=(ImageView)listView.findViewWithTag(imageUrl);
  31. if(imageViewByTag!=null){
  32. imageViewByTag.setImageDrawable(imageDrawable);
  33. }
  34. }
  35. });
  36. imageView.setImageDrawable(cachedImage);
  37. //SetthetextontheTextView
  38. TextViewtextView=viewCache.getTextView();
  39. textView.setText(imageAndText.getText());
  40. returnrowView;
  41. }
  42. }

这里我们没有加载完iamge之后直接设定到相应的ImageView上 ,而是通过Tag查找,这里我们重用的View 这里有个listView的引用来通过Tag查找 可见 CallBack的实现

  1. ImageViewimageViewByTag=(ImageView)listView.findViewWithTag(imageUrl);
  2. if(imageViewByTag!=null){
  3. imageViewByTag.setImageDrawable(imageDrawable);
  4. }

这里通过ViewCatch来减少了 findViewById的使用

  1. publicclassViewCache{
  2. privateViewbaseView;
  3. privateTextViewtextView;
  4. privateImageViewimageView;
  5. publicViewCache(ViewbaseView){
  6. this.baseView=baseView;
  7. }
  8. publicTextViewgetTextView(){
  9. if(textView==null){
  10. textView=(TextView)baseView.findViewById(R.id.text);
  11. }
  12. returntitleView;
  13. }
  14. publicImageViewgetImageView(){
  15. if(imageView==null){
  16. imageView=(ImageView)baseView.findViewById(R.id.image);
  17. }
  18. returnimageView;
  19. }
  20. }

总结:这里主要做了三点优化

  • 在单一线程里加载图片
  • 重用列表中行
  • 缓存行中的View
分享到:
评论

相关推荐

    wpf 异步加载图片

    wpf 异步加载图片 非常好的

    ImageView异步加载图片ImageLoaderSample.zip

    这个可以实现ImageView异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画。解决了:1. listview加载oom问题 2. listview加载时卡顿的现象 3. listview加载时item中图片重复错位等情况 可以...

    Android开发中批量异步加载网络图片的方法

    1、采用异步加载的机制。 2、编写自定义适配器。 3、本例中传的是数组,可根据个人需要传list集合等。

    【JavaScript源代码】vue ElementUI实现异步加载树.docx

     本文实例为大家分享了vue ElementUI实现异步加载树的具体代码,供大家参考,具体内容如下 路由文件修改 import List from '@/components/list.vue' import Add from '@/components/add.vue' import Tree from ...

    jsp实现局部刷新页面、异步加载页面的方法

    局部刷新页面、异步加载页面方案: 1.在jsp页面需要刷新的地方增加一个控件 &lt;div id=courseList&gt; 2.新建一个jsp页面:aaa.jsp(用来放置需要刷新的内容) 3.将id为courseList的dom标签重新赋值为需要的页面,就能...

    Android程序开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)

    例子中用于解析Json的Gson请自己Google下载 主Activity: package COM.Example.Main; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java....

    网页页面图片批量下载

    异步分析下载采取的策略是同时分析同时下载,即未等待数据全部分析完毕就开始把已经分析出来的图片链接开始下载。下载成功的均在List框链接前面划上了√ ,未能下载的图片有可能是分析错误或者是下载异常。 1. ...

    Lazyloading:listview 的异步加载

    Lazyloadinglistview 的异步加载功能简介功能为读取 /system/app 下的apk,然后从apk中获取每个应用程序的图标和名字每个apk消息的获取都增加了Thread.sleep() 模拟网络下载所消耗的时间。。。(学校上网收费,省点...

    listview实现显示异步图片进度条效果

    listview实现显示异步图片进度条效果,这个源码效果是listview使用进度条显示异步下载图片的进度,看网易新闻里面的轻松一刻的图片下载,也想写一个,轻松一刻里面也是用listview实现的,图片下载原理使用线程池来...

    使用CursorLoader异步加载数据

    Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题。在API 11之前可以通过下载支持库,来使之前的系统支持此功能。 下面是一个例子: public class ListViewLoader ...

    react-router4 配合webpack require.ensure 实现异步加载的示例

    实现异步加载的方法,归根结底大都是根据webpack的require.ensure来实现 第一个是自己使用require.ensure实现, 第二种 使用loader实现 今天我们说的是使用bundle-loader来实现,这样代码更优雅些。 首先需要安装...

    推荐一款Android安卓app开发框架_有超多的控件特效.zip

    list分页,grid分页,下拉刷新,进度框,图片轮播,表格,多线程下载器,侧边栏,图片上传,轮子选择,图表,Tab滑动,日历选择器 网络下载,多线程与线程池的管理,数据库ORM,图片缓存管理,图片文件下载上传,...

    photoselect-仿QQ本地图片选择,包括单选,多选时图片顺序标注.zip

    这里的查询语句是根据文件名字来过滤的,只要图片路径包含文件夹路径的,则为该文件夹下的图片 3.UI交互 首先在展示所有包含图片的文件夹时,异步加载有图片的文件夹,读取成功后列表展示,这里用的RecyclerView...

    LINQ-Async:用于异步任务的C#LINQ异步扩展方法库

    下载 PM&gt; Install-Package Z.Linq.Async LINQ异步扩展 问题 您要异步使用LINQ方法。 解决方案 支持所有LINQ扩展方法和重载。 您可以轻松创建任何异步任务。 // Using Z.Linq public Task&lt;IEnumerable&gt;&gt; ...

    Android代码-这是一个专用于解决Android中网络请求及图片加载的缓存处理框架

    这是一个专用于解决Android中网络请求及图片加载的缓存处理框架 项目目标 本项目是作为实验项目,不保证其稳定性及可靠性 因为缓存业务的复杂性,本项目尽可能适应更多的使用场景 目前考虑到的,会实现的功能清单,...

    vue 使用vant插件做tabs切换和无限加载功能的实现

    样例: 1.创建vue项目,不再详述 2.引入vant 之前用过很多插件做这个功能,但是效果都不尽人意,出现各种问题,直到遇到vant这个插件,完美的解决了这些小问题,如有问题,欢迎联系我 安装依赖 ...

    动画,控件、工具类

    包含了大量的开发常用手段如网络下载,多线程与线程池的管理,数据库ORM,图片缓存管理,图片文件下载上传,Http请求工具,SOAP工具类,异步Task,常用工具类(字符串,日期,文件处理,图片处理工具类等),能够使...

    C#使用semaphore来管理异步下载请求的方法

    本文实例讲述了C#使用semaphore来管理异步下载请求的方法。分享给大家供大家参考。具体实现方法如下: var semaphor = new Semaphore(50, 50); // We allow at most 50 threads for crawling var resultPins = new ...

    jquery 通过ajax请求获取后台数据显示在表格上的方法

    今天小编就为大家分享一篇jquery 通过ajax请求获取后台数据显示在表格上的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    Android开发之HttpClient异步请求数据的方法详解【附demo源码下载】

    本文实例讲述了Android开发之HttpClient异步请求数据的方法。分享给大家供大家参考,具体如下: 前面一篇Android开发笔记之:AsyncTask的应用较为详细的讲述了Asynctask的原理与应用,这里来结合使用一下HttpClient与...

Global site tag (gtag.js) - Google Analytics