阅读本节,默认读者已经了解基本的ListView的优化技巧: ViewHolder, ConvertView
前边提到Ophone的ListView实现中有一个BUG。在我开发的过程中,使用了ListView的Header,放置两个按钮用来跳转到推荐的内容和“掌上应用汇”中的类似,它有4个按键用来导航到推荐的内容。
我使用的设备有5维的导航键,如果你一直用手操作,是不会出现任何问题的,因为手机一直处于TOUCH-MODE,如果用导航键,就会切换到NONE-TOUCH-MODE,不断按向下键切换到HEADER不可见,然后再不断按向上键切换到HEADER可见,这时上图中的4个按钮就会出现问题,表现为无法再收到onClick事件,而且按钮的按下的背景也无法显示(在正常的情况下一个按钮被按下时,会有黄色高亮)。在我的应用和“掌上应用汇”中都可以重现这个问题。可见Ophone中的ListView在处理HEADER View时存在bug,同样的应用程序在HTC Desire with MIUI上表现正常。
你可以使用本节介绍的内容来跳过这个bug,把要显示的View做为List中的第一个ITEM来模拟header效果。
而且我们的最终目标是
可以看到图中包含3中不同的ITEM
a) 灰色的title部分
b) 普通的条目
c) 当前title中更为详细”更多“
因为在ListView调用Adapter的
方法时,会把已经不可见的条目传回来,这样的好处是你不用创建一个新的View,只要使用传入的View,更新上面的内容就可以了,这样做可以大大的节约内存资源。
使用的方法就是判断convertView是否为null,如果不为null就使用,如果为null就创建新的。
在我未了解Adapter的机制前,为了实现返回3种不同的View,我写了一个FrameLayout,里面同时有这3种ITEM,只是根据不同的类型来改变不同View的setVisibility为GONE或者VISIBLE。
通过这种方法也能实现,而且使用convertView,效率也不算太差。缺点也很明显,明明创建了3套View,只是使用其中的1/3,如果有更多种,那就更浪费了。
其实ListView和Adapter早就已经为这种情况考虑到了,ListView在传回convertView时已经考虑到,对于不同的类型就缓存在不同的队列中,在调用时传回。请参考Adapter的如下方法:
所以我们只要修改下adapter的实现就可以节约不少的资源。
修改后的:
如果模拟header的话就修改TOTAL_TYPE_COUNT = 4,再添加一种type就可以了,而且可以把这个header放到你想要的任何位置。这样就可以跳过那个bug.