ListView/gridView代码优化viewHolder精解--converView使用
2015-08-16 21:37
288 查看
大家都知道listview的使用和MVC框架有一定的异曲同工—-我们会在activity里面异步获取到一定的数据项再传给adapter,由adapter将数据与视图有机结合—–adapter 就是control——
在以前我也在写adapter的时候遇到很多问题,这篇也是精要的写明listView和gridView里面viewHolder和converView的使用
先附上adapter代码—–就几行,,比较简单,明了——-
啰嗦一下 ——- getView() 方法是 ListView 或者 gridView 获取 View 的代码块——–gridView是根据getCount返回的值来确定行数的—-getCount 返回0就不显示 listView 和 gridView
当我们数据量大的时候也就意味着 ListView 可能要显示成百上千行–如果我们不使用进行代码优化 那么就会每一加载一个view 就会调用一次——-inflate——–findViewById——–
这无疑会让我们的程序卡顿—-滑动多了还会out of memory————
那来看解决方法我们来看看converView是什么—–它是android提供的,当listView里面的view移除屏幕后重复使用的view—也就是一个listView 有10000+项—-adapter一共就屏幕上能显示的item那么多项实例View 如下图所示
这个Holder的属性是我们加载的布局 里面的组件实体,也就是我们要显示的item里的小组件
为了避免重复加载布局文件和组件然后在每一个要显示View里面 setTag(Holder)(View的Tag属性,可携带对象和键-值对,不知道自行百度)
当他铺满了,返回一个converView——————因为这个converView 就是我们屏幕上被移除的View——————
所以每一个View的 Tag 里面都有我们放进去的holder我们只需要getTag就可以获得holder也就是不再需要加载布局及findView了————这也是算法里的用空间换时间思想—————用Tag多携带的数据换取频繁inflate和findView——
最后附上MainActivity代码——
在以前我也在写adapter的时候遇到很多问题,这篇也是精要的写明listView和gridView里面viewHolder和converView的使用
先附上adapter代码—–就几行,,比较简单,明了——-
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ListViewAdapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">BaseAdapter</span> {</span> Context context; List<ListViewItem> list;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 闯过来的数据</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getCount</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> list.size(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ListViewAdapter</span>(Context context, List<ListViewItem> list) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.context = context; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.list = list; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="box-sizing: border-box;">getItem</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-title" style="box-sizing: border-box;">getItemId</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> View <span class="hljs-title" style="box-sizing: border-box;">getView</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> position, View convertView, ViewGroup parent) { Holder holder; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 这个converView和holder是什么?---查看底部说明</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (convertView == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { holder = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Holder(); convertView = LayoutInflater.from(context).inflate(R.layout.listview_item, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>); holder.title = (TextView) convertView.findViewById(R.id.tv_title); holder.text = (TextView) convertView.findViewById(R.id.tv_text); convertView.setTag(holder); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { holder = (Holder) convertView.getTag(); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置---item的标题---文本</span> holder.title.setText(list.get(position).title); holder.text.setText(list.get(position).text); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> convertView; } class Holder { TextView title; TextView text; } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li></ul>
啰嗦一下 ——- getView() 方法是 ListView 或者 gridView 获取 View 的代码块——–gridView是根据getCount返回的值来确定行数的—-getCount 返回0就不显示 listView 和 gridView
当我们数据量大的时候也就意味着 ListView 可能要显示成百上千行–如果我们不使用进行代码优化 那么就会每一加载一个view 就会调用一次——-inflate——–findViewById——–
这无疑会让我们的程序卡顿—-滑动多了还会out of memory————
那来看解决方法我们来看看converView是什么—–它是android提供的,当listView里面的view移除屏幕后重复使用的view—也就是一个listView 有10000+项—-adapter一共就屏幕上能显示的item那么多项实例View 如下图所示
回来细看代码:
当converView==null–——————也就是屏幕上还没铺满item时 我们就加载item的布局文件,及findView布局文件里面的View >>>> 并且创建holder ————这个Holder的属性是我们加载的布局 里面的组件实体,也就是我们要显示的item里的小组件
为了避免重复加载布局文件和组件然后在每一个要显示View里面 setTag(Holder)(View的Tag属性,可携带对象和键-值对,不知道自行百度)
当他铺满了,返回一个converView——————因为这个converView 就是我们屏幕上被移除的View——————
所以每一个View的 Tag 里面都有我们放进去的holder我们只需要getTag就可以获得holder也就是不再需要加载布局及findView了————这也是算法里的用空间换时间思想—————用Tag多携带的数据换取频繁inflate和findView——
最后附上MainActivity代码——
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> List<ListViewItem> dataList;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// listView 使用的数据</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ListView listView; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> ListViewAdapter listViewAdapter;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// listView 数据的适配器</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取组件</span> loadData();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加载数据</span> listView.setAdapter(listViewAdapter);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置适配器---传入context---传入数据</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">findView</span>() { dataList = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<ListViewItem>(); listView = (ListView) findViewById(R.id.list_view); listViewAdapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ListViewAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, dataList); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加载数据项</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loadData</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20000</span>; i++) { dataList.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ListViewItem(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Title: "</span> + i, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"*********************"</span>)); } } }</code>
相关文章推荐
- LRU缓存介绍与实现 (Java)
- C++Template 读书笔记 第五章
- 相见恨晚的python库
- Mac 學習系列之Python Challenge 1-10
- 去哪网实习总结:java读写excel表格(JavaWeb)
- C/C++ -- 代码技巧及优化
- java NIO 实现
- java socket 通信示例
- Java深入 - Java 内存分配和回收机制-转
- Java关键字final、static使用总结
- Python中类的属性的访问控制
- eclipse从数据库逆向生成Hibernate实体类
- 树莓派 GPIO python
- seci-log 1.11 发布,日志分析软件增加 ftpserver 等功能
- C++手稿:类的静态和常量成员
- 正确编译和运行带package的文件(使用javac和java命令行)
- C++手稿:对象的生命周期,构造与析构
- 10 错误和异常 - 《Python 核心编程》
- POJ2007--Scrambled Polygon
- c++从零开始学起(关于迭代器的使用)