一点经验教训:RecyclerView的Adapter中getItemCount()不起作用的原因

 很久没写过项目了。最近重新拣回以前的老本行Android开发,写了个小项目。

今天,我在写项目的过程中,用到RecyclerView时,发现其Adapter中重写的getItemCount()方法不起作用。Adapter中使用了两种item view:一个是列表的标题item view,用来显示list数据源有多少个数据,另一个是list列表中的详细数据。如果List中存在数据时,该列表至少会有两项视图。

在调试的过程中,数据源中的数据更新到了6个。本来列表中应该显示7项的(1项标题+6项数据),结果只显示了2项(1项标题+1项数据)。因此,仔细检查了Adapter有没有写错,还有RecyclerView有没有初始化错误。一一排除后,发现错误依然在。

因此,我打开了调试工具,打断点一步步调试。

一开始追踪到RecyclerView.Recycler.tryGetViewHolderForPositionByDeadline()中时,其传进来的参数一直只有position=0和position=1两项,并没有position=2-6。正常的话,position是会依次传进2-6四个值的。判断是上一个调用并没有把position剩余的值传进来,于是,通过调用栈往上追踪。

通过追踪发现,tryGetViewHolderForPositionByDeadline()这个方法是被LayoutManager的LayoutState.next()方法调用的,此方法用来获取下一个布局的View。继续往上追踪,经过一个layoutChunk()方法,最终定位到了LayoutManager.fill()方法中。

在fill()方法里面,有一个while循环用来判断是否还有其他元素。判断条件是(layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)。经判断,后者layoutState.hasMore(state)是满足的,因此,很有可能就是前者(layoutState.mInfinite || remainingSpace > 0)这个条件没符合要求,才导致没办法渲染其他列表元素。

其remainingSpace的定义是 int remainingSpace = layoutState.mAvailable + layoutState.mExtraFillSpace;。会不会是我的remainingSpace不够了呢?

这时,我心血来潮地检查了一下每项的布局文件。果然,在布局文件中,rootview的高度被我设成了match_parent,导致渲染了一项之后,这一项就直接布满屏幕剩下的高度空间了。真粗心!


通过这个教训,我懂得了以下道理:

1. 写布局文件时,一定要留心用match_parent的地方。

2. 善用调试工具。调试时,首先心里要明白,自己到底要通过调试解决什么问题。然后善用调用栈,去从栈顶开始一级一级往下分析,看看整个调用链是怎样的,可能在哪里出现了问题。

3. 使用调试工具时,经常会被自己设置的跳来跳去的断点给打乱了思路,导致不知道从何处下手。这时候,一定要停下来自己好好地想想,我要解决什么问题,并且这个问题可能会在调用栈的哪个地方出现。想清楚了再继续调试。

评论

此博客中的热门博文

macOS安装配置libnfc小记