我们每一个Android开发人员对ListView的使用肯定是很熟悉的,然而多少人能真正的懂ListView的缓存机制呢,说白了就是ListView为了提高效率,而内部实现的一种优化,牺牲一点内存。而这种优化就需要复用ItemView(也就是item对应的View).那么下面楼主来对ListView和RecyclerView的item复用问题做一个深入的讲解先来一张大家学习的时候都遇到过的图这里写图片描述看不懂也没啥事,可以接着往下看,先有一个直观的认识首先来解答几个问题为什么会存在Item复用问题答:ListView内部为了优化而建立的复用机制,在下面方法中第二个参数就是ListView传递给你,让你进行复用的View.如果你不想复用listview传递给你的View,那你每次都需要创建一个新的View进行返回,这样子是肯定不会出现复用问题的,但是性能却是很消耗的。
  
  {}123412342.为什么上述的getView方法中第二个参数有时候为null呢因为ListView默认缓存一页的View,什么叫一页,也就是你当前listview界面上有几个Item可以显示,listview就缓存几个.
  
  当现实第一页的时候,由于没有一个Item被创建,所以第一页的Item的getView方法中的第二个参数都是为null的假如listview只能最多显示8条记录,则第一页显示的时候listview内部缓存了这8个itemView.当第九条记录出现在视野中的时候,listview就会在调用getView方法的时候在第二个参数处传入之前用过的itemView。
  
  3.为什么需要ViewHolder呢?这个又是干嘛的为什么需要 上述我们谈到itemView的复用是为了性能,那么ViewHolder同样也是为了提高性能.我们都知道我们要显示列表数据.就要在getView方法中拿到对应下标的数据然后对itemView中的控件进行设值,所以我们需要用到findViewById(int id)方法来找到控件,并且强转成我们想要的类型之后,然后设置数据,而findViewById(int www.huafanyun.cn id)方法在列表滚动的时候频繁调用getView方法的时候也是一个比较消耗性能的操作.所以ViewHolder来了是干嘛的 为了在列表滚动的时候,频繁调用getView方法的时候尽量提高性能.我们可以使用一个普通类,这个类通常就起名字为了,当创建itemView的时候,我们也把里面要用到的控件也找到,然后放在类中,然后再通过itemView.setTag(Object ob)方法实现一个itemView和一个进行绑定.
  
  经过上述的操作,如果在getView方法中传入了复用的itemView,那么我们可以毫不客气地从里面拿出这个itemView对应的ViewHolder,从而避免了去调用多个findViewById(int id)去找到控件并设值.因为之前你把找到的控件都放在了ViewHolder中扩展 如果你的itemView中只有一个控件需要显示,那么ViewHolder就不需要了,你可以直接把这个控件和itemView进行关联,也就是你需要深刻理解ViewHolder的作用,它是为了把你找到的多个控件和itemView关联。所以当你只有一个控件的时候,这个ViewHolder就不需要啦方法直接把这个控件设置上去就可以啦,复用的时候直接拿出来那么主要的问题解答完了,总得写点代码来让大家更深刻的体会一下.
  
  博主几乎会重现我们开发中的常见问题,来对应的讲解方法在什么时候调用回答:在每一个item从不可见变为可见的时候动手实践实现一个简单的列表,使用ListView控件,并且Item中有复选框的xml文件1234567891011121312345678910111213就是一个列表控件的Item的xml1234567891011121314151617181920123456789101112131415161www.feilafan.cn7181920的适配器}}}}}}1www.yunfanfei.cn2345678910111213141516171819202122232425262728293031323334351234567891011121314151617181920212223242526272829303132333435这代码非常简单,不再啰嗦代码}}}12345678910111213141516171819202122232425261234567891011121314151617181920212223242526代码贴完了,都是非常的简单,先看下运行效果这里写图片描述这里很需要你们关注的是我们的适配器中的getView中的代码}12341234我们上面说过了方法中第二个参数是ListView会传的itemView,提高效率用的,而这里博主先不用,每次调用getView都会创建一个新的View然后返回实现一个小目标,嗯:奇数的Item中的复选框要被选中那么很容易,只需要这样子//找到文本框//设置文本内容//找到复选框如果是奇数}}12345678910111213141516171234567891011121314151617代码也很简单,就是找到了创建的布局item中的文本控件和复选框,然后设置相应的内容看效果这里写图片描述我们可以看到,功能实现了,而且没有出现任何问题,比如常见的复用问题,嗯喂喂喂,我们没复用回传的View,哪里来的复用问题啊,哈哈哈,所以我们的列表是肯定没有任何问题的,因为根本没有复用,性能是最差的一种写法实现一个小目标,复用Item,嗯}//找到文本框//设置文本内容//找到复选框如果是奇数}}1234567891011121314151617181www.yunfeizao.cn 920212223241234567891011121www.feiyunfan.cn31415161718192021222324这段代码改动的地方就是方法最开始,判断了一下回传给我的view是不是为null,为null的情况博文最开始已经讲过了如果为null就创建一个新的,如果不是就直接赋值给item,达到条目的复用!
  
  那我们看看效果呗!
  
  这里写图片描述请大声的告诉我,发生了什么?复用问题没错,复用问题出现了,博主给大家重现了错误那么这里是怎么引起的呢?
  
  只有知道其中的原理,你解决问题才能快准狠!
  
  首先我先帮大家统计一下创建Item的次数这里写图片描述可以看到,我用一个变量记录创建的次数,我重新运行这里写图片描述从App运行到滑动来滑动去,我们可以看见,最开始创建了16次,然后随着滑动多来了一次,你可以使用截图定格一下动图,你会发现这个列表最多显示17条记录(当然了你的界面是多少个和我这个界面是不同的,反正就是界面能显示的Item最多个数),所以证明了上面的一个观点,ListView默认缓存一个界面的Item个数原理所以当我们复用ListView回传的View的时候,这个View是被之前使用过的,也就是说给你的这个View保存了之前用过的状态这里的情况就是给你的view刚好是之前复选框被选中的那个View,所以就造成复用啦解决方法对产生问题的控件进行初始化,初始化时什么意思呢?
  
  意思就是说,把出问题的控件,状态还原一下看代码!
  
  这里写图片描述别看了,就是框框里面的一句话,是不是感觉很简单呀,如果你知晓原理,为什么这样子就没有了复用的问题呢?
  
  因为如果给你的View里面的复选框是被选中的,这里你对他还原了呀,所以就ok啦使用上面我们也说了ViewHolder的作用和使用的必要性,那么博主直接来用一下吧由于getView内部稍微改动有点大,我贴上Adapter中的代码}}}}对应的试图//找到文本框//找到复选框//让item和ViewHolder绑定在一起//复用ListView给的View//拿出}//设置文本内容//还原状态如果是奇数}}/*** 用于存放一个ItemView中的控件,由于这里只有两个控件,那么声明两个控件即可*/}}1234567891011121314151617181920212223242526272829303132333435www.feiyunyl.cn3637383940414243444546474849505152535455565758596061626www.feihuayl.cn 36465666768697071721234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666www.fsmaxbuy.com/768697071721.如果复用的View为null,我们需要创建一个新的item,同时也创建了一个ViewHolder,然后把条目视图中的控件通过findViewById方法寻找到中,然后我们说了需要和条目视图进行绑定,所以调用了setTag方法2.而另一边,如果复用的View不是为null,那么直接拿过来用,并且从里面拿出ViewHolder,因为每一个复用的ViewHolder肯定是经过1处创建并且返回的到这里为止,一个完成的列表的展示和优化已经完成啦,并且中间讲述了复用问题是如何产生的,如何解决!

ListView复用和优化详解的更多相关文章

  1. 代码优化>>>Android ListView适配器三级优化详解

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:点击打开链接  http://blog.csdn.net/qq_32059827/article/details/52718489 ...

  2. [推荐]T- SQL性能优化详解

    [推荐]T- SQL性能优化详解 博客园上一篇好文,T-sql性能优化的 http://www.cnblogs.com/Shaina/archive/2012/04/22/2464576.html

  3. lucene、lucene.NET详细使用与优化详解

    lucene.lucene.NET详细使用与优化详解 2010-02-01 13:51:11 分类: Linux 1 lucene简介1.1 什么是luceneLucene是一个全文搜索框架,而不是应 ...

  4. Nginx配置项优化详解【转】

    (1)nginx运行工作进程个数,一般设置cpu的核心或者核心数x2 如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor / ...

  5. MySQL数据库优化详解(收藏)

    MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * ...

  6. Nginx服务优化详解

    Nginx服务优化详解 1.隐藏Nginx版本信息 编辑主配置文件nginx.conf,在http标签中添加代码 server_tokens off;来隐藏软件版本号. 2.更改Nginx服务启动的默 ...

  7. MySQL-5.5.32 配置文件优化详解

    目录 MySQL-5.5.32 配置文件优化详解 一.配置文件说明 2.my-medium.cnf 3.my-large.cnf 4.my-huge.cnf 5.my-innodb-heavy-4G. ...

  8. ListView嵌套GridView使用详解及注意事项

    ListView嵌套GridView即ListView的每个Item中都包含一个GridView:需要注意的是由于ListView和GridView都是可滑动的控件. 所以需要自定义GridView, ...

  9. lucene.NET详细使用与优化详解

    lucene.NET详细使用与优化详解 http://www.cnblogs.com/qq4004229/archive/2010/05/21/1741025.html http://www.shan ...

随机推荐

  1. HTML5 API 浏览器支持情况检测

    HTML5发展到现在,虽说没有大规模的普及,但在我们日常生活中,也很容易见到了,HTML5的游戏.网站.应用也是层出不穷.而作为前端人员,也应该多了解这些API为以后应用打基础,下面我将给大家介绍 H ...

  2. uva 10718 Bit Mask(贪心)

    题目连接:10718 Bit Mask 题目大意:给出一个T, 和一个下限L, 上限R, 在[L, R]之间找一个数, 使得这个数与T做或运算之后的数值最大 输出这个数. 解题思路:将T转换成二进制, ...

  3. 微信支付 V3版

    本人小菜鸟一仅仅.为了自我学习和交流PHP(jquery,linux,lamp,shell,javascript,server)等一系列的知识,小菜鸟创建了一个群.希望光临本博客的人能够进来交流. 寻 ...

  4. 最简单的自定义适配器adapter

    下面是一个非常简单的自定义适配器的总体源码,从这个源码入门,就可以慢慢学会适配器了 适配器的作用: 完成数据和界面控件的绑定,把数据绑定到界面的现实控件条目上(对于listView,应该是listVi ...

  5. pcap文件格式

      pcap文件格式 pcap文件格式是bpf保存原始数据包的格式,很多软件都在使用,比如tcpdump.wireshark等等,了解pcap格式可以加深对原始数据包的了解,自己也可以手工构造任意的数 ...

  6. Glossary of Terms in the JavaTM platform --reference

    http://docs.oracle.com/javase/tutorial/information/glossary.html field :A data member of a class. Un ...

  7. telnet的使用

    1.要打开 telnet 不是内部或外部 命令 解决方案: 程序添加删除功能,添加即可 或法二 C:\WINDOWS\system32\telnet.exe (或用C:\WINDOWS\system3 ...

  8. 让iOS开发变得更有效率-分类、工具类

    在工作中整理的一些分类与工具类,分享给大家.这些工具类可以减少项目中的代码量,让代码变得更简洁,可以大大的提升项目的效率,直接拖到项目中使用即可.下载地址:https://github.com/lee ...

  9. .net mvc 发布部署到机器上

    这样会自动在C:\Inetpub\wwwroot 会出现这个文件夹. 上述步骤都是在安装了 VS2010.MVC3.0和的电脑上操作的 接下来进行服务器的部署 :1. 安装Microsoft .net ...

  10. angularJs 使用中遇到的问题小结【二:购物车引起的问题思考】

    问题描述 :购物车引起的问题思考 业务逻辑是这样的:我商品加入购物车后,——>点击购物车图标——>进入订单列表(这里的数据只有首次会加载服务器数据,后面就不会执行控制器的方法了,这里的跳转 ...