RecyclerView使用之——数据刷新混乱及解决方案

初学Android,首次在项目中运用发生了RecyclerView刷新发生混乱的问题,困扰好久,终于解决,分享如下。

【问题现象】

项目中用RecyclerView做了一个医生排班列表,用于显示所有医生的排班信息,RecyclerView的一个项目(即一个医生),可以通过点前一周,下一周按钮查看不同周次的该医生的排班情况,编码很顺利,网上很多RecyclerView的例子,但在测试时发现,当第一次点击其中一个医生的下一周按钮时,结果该医生的数据却没有刷新,前一个医生的数据却被刷新了。

【调查过程】

通过debug发现了以下有趣的事情,在onBindViewHolder方法中,下一周按钮被点击时,被点击按钮所在项目(即holder对象)的ID假设为A,位置(即position)假设为7,在按钮事件被触发,通过Adapter.notifyDataSetChanged();触发RecyclerView刷新后,onBindViewHolder方法执行的时候,发现ID为A的holder的position发生了变更,不再是7了,而变成了6。holder的顺序发生了变更,但是adapter所绑定的数据的顺序却很正常,没发生变更,而这导致了上述现象的发生。

到底是什么原因导致position发生了变更呢?会不会是大牛的google开发人员的bug呢?如果是的话,android的开发者成千上万,早就发现这个问题并被反映解决了,又怎么能轮得到咱中大奖呢?所以说问题的原因很有可能是自己使用不当。但毕竟是android菜鸟,怎么解决毫无头绪,还是debug进源码看看到底为什么position会发生变更吧。我发现holder对象是在RecyclerView的getViewForPosition(int position)方法中被生成的。再往下细看,发现有一行给holder赋值的判断条件if (mAdapter.hasStableIds())没能走进去。我感觉很蹊跷,看看StableIds是个什么东西,有什么作用吧。hasStableIds()方法的注释如下:

/**
 * Returns true if this adapter publishes a unique long value that can
 * act as a key for the item at a given position in the data set. If that item is relocated
 * in the data set, the ID returned for that item should be the same.
 *
 * @return true if this adapter's items have stable IDs
 */
写得很明确,感觉自己的问题就是它导致的。问题定位到这里,很容易查到了许多类似的问题和解决方法。如下:

【解决方法】

首先,在绑定adapter给RecycleView之前,设定adapter的stableIds为true。

adapter.setHasStableIds(true);
recyclerView.setAdapter(adapter);

其次,在adapter中,需要重写getItemId方法。

@Override
public long getItemId(int position) {
    return position;
}
之后重新运行app,发现问题完美解决了。
 
  
更多RecyclerView的问题,可参阅如下文章。
http://blog.csdn.net/limonzet/article/details/56665727
 
  

你可能感兴趣的:(RecyclerView使用之——数据刷新混乱及解决方案)