由于之前写Scroller应用:ListView滑动删除遇到Item视图错位问题,观察发现第1item位置改变后,第1+10的item布局也跟着改变,如果使用ScrollView+ListView,把ListView的高度测量出来然后再滑动就不会出现错位问题,继续查看之所以间隔10,我屏幕上显示10条数据,这个就涉及到getCount()和getChildCount()问题,进一步追踪发现应该是ListView视图缓存的问题,其实这个问题跟数据是一样的,不过我们在Adapter的getView中根据不同的position设置不同的数据,这个动作是实时改变的,getChildCount()返回的是内存中的item数目,getCount()返回的是实际的数据数目,ListView中实际的item布局也就是getChildCount()的值,如果采用测量ListView设置其高度的话,那getChildCount()等于getCount(),在ListView中有这么一段代码
// Pull all children into the RecycleBin. // These views will be reused if possible final int firstPosition = mFirstPosition; final RecycleBin recycleBin = mRecycler; // reset the focus restoration View focusLayoutRestoreDirectChild = null; // Don‘t put header or footer views into the Recycler. Those are // already cached in mHeaderViews; if (dataChanged) { for (int i = 0; i < childCount; i++) { recycleBin.addScrapView(getChildAt(i), firstPosition+i); } } else { recycleBin.fillActiveViews(childCount, firstPosition); }
firstPosition是第一个可见的item的位置,recycleBin.addScrapView(getChildAt(i), firstPosition+i);缓存隐藏item的时候,都是使用getChildCount()内的现有的View视图,所以解决错位问题必须采用位置的标记来处理,而且标记也不能在自定义的item中进行,必须在外部例如自定义ListView中记录。在Scroller应用:ListView滑动删除中采用的是规避的方式,滑动就关闭之前打开的item,看了QQ消息列表也是滑动的话就隐藏删除按钮,我不知道是否规避这个问题,因为ListView内存的item数据一般大于屏幕可见的item数据,所以即使屏幕大也看不到。