Why ListView?
ListView 如果仅仅出于功能上的需求ListView可能没有存在的必要,ListView能作的事情基本上ScrollView也能胜任。ListView存在的最根本的原因在于它的高效(如何实现的?).ListView通过对象的复用从而减少内存的消耗,也减少了对象的创建从而也减少的cpu的消耗(在Androidk中创建View对象经常伴随着解析xml)。ListView的本质是一张bitmap(当然所有的控件文字等在屏幕上看到的最终都会变成bitmap),ListView会按照需求,根据Adapter提供的信息把需要的Item画出来显示在屏幕上,当屏幕滚动的时候会重新计算Item的位置并绘制出新的bitmap显示在屏幕上。这样听起来感觉可能不是很高效,但这样带的好处就是,每用为一第个Item 创建一个View对象,样式一样的对象可以共用一个View对象,减少了内存的消耗。而且ListView是事件驱动的,只有当需要的时候才会重新绘制,并且只会 绘制当前屏幕上所显示的Items.
How To Use?
ListView 离不开Adapter,通常的作法创建一个类继承BaseAdapter,Override getCount()和getView()等方法。生成这个类的对象,调用ListView的setAdapter()与ListViw进行绑定。
How Does It work?
ListView会调用跟其绑定的Adapter的getCount()方法知道有多少个Item需要展示,然后循环调用getView(int position, View convertView, ViewGroup parent)知道第position个Item该怎么画,并画出来直到把当前的ListView的空间填满。当Adapter当中的数据改变时,需调用notifyDataSetChanged ()告诉Adapter数据发生了变化或者给Adapter注册一个观察者registerDataSetObserver (DataSetObserver observer)。当Adapter得知与其绑定的数据己发生改变时间,会再次调用getCount()方法,并循环调用getView(int position, View convertView, ViewGroup parent)刷新当前页面。
Item 1 |
Item 2 |
Item 3 |
Item 4 |
Item 5 |
Item 6 |
Item 7 |
Item 8
|
当这个ListView 向上滚动需要创建一个Item9 同时,有些对象(比如Item1 )不在显示区域将看不到,这时android 将会把item1 的 引用传递给 Adapter.getView() 中的convertView这样我们就不用再创建一个View来存放Item9,只需要把原来的item1对象作下修改,就可以重复使用了 ;我们也不用担心convertView 是不是正确的类型,这个由系统保证,所以我们要作的就是把convertView 转换(经常需要向下转型)成我们自己的View 再给它赋值,in this case :(TextView) convertView.setText(“Item9”);
public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { //this would be first time to show the item,so we need to create it convertView = mInflater.inflate(R.layout.item, null); } //we grab the convertView,modify it and reuse it ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]); return convertView; }
调用方法所需要的消耗要比访问变量高得多,而上面的代码一次又一次的调用findViewById()方法,作着重复的事情。所以我们可以进一步进行如下优化: 创建一个类用来保存一些View的引用,这样我们就可以直接使用,而不用再调用findViewById().因为我们所保存的只是引用不是对象本身,所以不用担心会占用大量内存
static class ViewHolder { TextView text; ImageView icon; } public View getView(int position, View convertView, ViewGroup parent){ ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item_icon_text, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //we store the reference ,so that we don’t have to call findViewById() over and over again holder.text.setText(DATA[position]); holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); return convertView; }
上图是T-mobile g1上采集的的数据,现在看来可能现在不是很准确,但其性能上的差异还是很有参考价值的。
Tips & Tricks
ListView是为了大容量数据展示而设计的。如果数据量(Item的数量)不是很大,且用ListView实现起来比较麻烦,不妨换种思路,不使用ListView,而用ScrollView来实现。
如果Item信息布局比较复杂或者Item的数量很多,出于性能的考虑,建议自定义一个View组件实现需要的功能,而不是组合其它控件达到所要的效果。
ListView滚动变黑:在xml中给ListView增加一个属性android:cacheColorHint="#00000000" 。当ListVIew中有很多Item,有时候需要快速的滚动。比如从第一个Item滚动到第600个Item这个时候,中间的很多Item对用户来说意义不是很大,但android却要调用 adapter.getView()方法将这些Item逐一画出,并且因为滚动很快用户不希望有任何的延迟。这在一些低端手机比如g1,是很难作到的。所以google工程师想出的一个办法是在滚动的时候,让屏幕变黑用一张黑色bitmap盖住ListView,而不去绘制中间过程中的很多Item,从而提升性能。
Item有自己的背景盖住了Selector光标:在xml中给ListView增加一个属性:android:drawSelectorOnTop="true"这样光标就会跑到Item上面的图层,解决我们的问题。
Snippets
多选框ListView
带有进度条的ListView,多个子线程刷新各自的进度,如果子线程很多那么刷新就会变得很频繁,我们可以由一个handler负责统一刷新,这样我们就要以增加一些额外条件限制刷新的次数和条件
分批加载的原理很简单,给ListView添加一个OnScrollListener监听滚动事件,当用户滚动到屏幕到特定的位置时加载新数据,并给LIstView加一个正在加载的footerView,当加载数据结束时再把这个footerView去掉。
相关推荐
对listview各种adapter的总结
NULL 博文链接:https://andensy.iteye.com/blog/789956
如何使用ListView 总结 如何使用RichEdit 总结 在使用RichEdit时,如何插入图片,如何使字体换行等操作。
Android自定义adapter的listview代码
把android中重要的listview的用法进行归纳总结
开发中遇到的各种listview的效果,全在这里,两年来对listview的总结。下载以后可以直接使用。
listView适配器SimpleAdapter和SimpleCursorAdapter细节总结
在此对各种方法做一个个人的总结评价。 主要的方法有四种: 1、手动设置ListView高度(比如把高度设置为200dp) 评价:特别简单无脑,但是大大提高了代码的耦合性,比较适合“图方便”的新手。 2、使用单个...
C#中ListView控件的虚模式使用方法 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
详细介绍了ListView比较常用的三种适配器的用法,基于代码一步一步完成,自己学习后的一点总结
这是我一下午的总结,listview常用的方法,和三种基本适配器以及实际开发中通过泛型的适配器以及万能适配器,如果大家感兴趣,这里有文章的地址:http://write.blog.csdn.net/postlist
Treeview和ListView使用 这个都是本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
对VB中的listView控件用法的总结 主要包括:复选框数值获取 右击菜单 ctrl多选值的获取 双击复选框的选中等 双击条目 选中复选框 右击 “测试1”,输出左击和右击选中的行数 右击“测试2”,输出复选框选中的行数 ...
学习C#必经之路,入门级知识总结,笔记本知识概况,走一步再走一步
Android ListView的下拉刷新,在实际开发中是很常用的,所以这里总结了,ListView下拉刷新的一个Demo。 该Demo的源码来自于github上的一个开源代码,只不过这里是将所需的library导入到项目中,然后将...
ListView行移动 本人收藏了3年的资源 现放出 都是总结了很多系统 软件项目实施过程中的经验的 慢慢积累的
listview相关问题的总结和处理
总结探讨,此文档可以快速帮助初学朋友实现使用listview进行分页
Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法: 首先我们给出一个没有任何优化的Listview的Adapter类,我们这里都继承自BaseAdapter,...