ListView的getViewTypeCount与getItemViewType

2013-12-25

对于Listiew来说,getViewTypeCount 和getItemViewType主要用于为不同的列表项目提供不同的视图view, 主要用法在有人已经在《ListView 和 Adapter 的基础》中描述得比较清楚了, 但是文章有一点没说,就是下面这三行:

private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

这三行是非常重要的,因为TYPE_ITEM和TYPE_SEPARATOR的值最后是被当作一个数组的索引来使用的。

我们已经知道ListView的隐藏列表行开始被显示的时候,行View是被缓存在RecycleBin中的,那么RecycleBin缓存的顺序是什么样的呢?以上面的代码为例,大致过程如下(简化过程,并不代表实际有这些类):

mRecycler[RecycleBin]
1.mRecycler.setViewTypeCount(mAdapter.getViewTypeCount()); 
    --> int[] mRecycler.viewCache = new View[TYPE_MAX_COUNT] 
        --> int[] mRecycler.viewCache = new View[2];
2.mRecycler.addScrapView(child1); 
    --> mRecycler.viewCache[child.viewType] = child1.view 
        --> mRecycler.viewCache[TYPE_ITEM] = child1.view 
            --> mRecycler.viewCache[0] = child1.view
3.mRecycler.addScrapView(child2); 
    --> mRecycler.viewCache[child.viewType] = child2.view 
        --> mRecycler.viewCache[TYPE_SEPARATOR] = child2.view 
            --> mRecycler.viewCache[1] = child2.view

可以发现,一旦ITEM_N的定义不符合数组的规范,那么溢出是非常常见的。我一开始犯的错误就是TYPE_1和TYPE_2…TYPE_N都是随意定义的, 结果报的错误居然是数组溢出,查看了ListView源码之后才发现原来具体的执行过程,以前实在是忽略了。。。。

所以综合看来,google这么做实在是有些不好理解,为什么不直接使用map来存储呢?那样就容易理解得多。


文档信息 by XiaoPingYuan

版权声明:自由转载-非商用-非衍生-保持署名。发表日期:2013-12-25 by XiaoPingYuan(https://xesam.github.io/)