【发布时间】:2016-10-19 13:05:09
【问题描述】:
我有一个包含 13 个项目的列表(尽管可能会添加或删除项目),位置为 0-12。当第一次显示包含 RecyclerView 的片段时,只有位置 0 到 7 对用户可见(位置 7 只有一半可见)。在我的适配器中,我 Log 每次绑定/绑定视图持有者(如果语法适用于此,则为 idk)并记录其位置。
适配器
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder() position: " + position);
...
}
从我的Log 我看到位置 0-7 已绑定:
我有一个selectAll() 方法,可以通过适配器位置获取每个ViewHolder。如果返回的holder 不是null,我使用返回的holder 来更新视图以显示它已被选中。如果返回的持有者是 null,我调用 selectOnBind() 一个方法,该方法在该位置更新标记视图以显示它在绑定时而不是实时选择,因为它当前未显示:
public void selectAll() {
for (int i = 0; i < numberOfItemsInList; i++) {
MyAdapter.ViewHolder holder = (MyAdapter.ViewHolder)
mRecyclerView.findViewHolderForAdapterPosition(i);
Log.d(TAG, "holder at position " + i + " is " + holder);
if (holder != null) {
select(holder);
} else {
selectOnBind(i);
}
}
}
在这个方法中我Logholder连同它的位置:
所以到目前为止一切似乎都很正常。我们有位置 0-7 显示,根据Log 这些是绑定的位置。当我在不更改可见视图(滚动)的情况下点击selectAll() 时,我看到位置 0-7 已定义,8-12 为null。到目前为止一切顺利。
这就是有趣的地方。如果在调用selectAll() 之后我进一步向下滚动列表位置 8 和 9 不显示它们已被选中。
检查Log 时,我发现这是因为它们从未被绑定,即使它们被报告为null:
更令人困惑的是,这种情况并非每次都发生。如果我首先启动该应用程序并对其进行测试,它可能会起作用。但它似乎在之后毫无失败地发生。我猜这与被回收的视图有关,但即使如此,它们也不必绑定吗?
编辑 (6-29-16)
在 AndroidStudio 更新后,我似乎无法重现该错误。它按我的预期工作,绑定空视图。如果这个问题再次出现,我会回到这个帖子。
【问题讨论】:
-
像你一样选择你的行不是一个好习惯(而且它不起作用),更好的方法是有一个选择项目的列表(或地图),然后在
onBind检查位置是是否存在于您的列表中。如果存在,则将行更改为选中,否则显示正常行。 -
这就是我所拥有的。但是,如果您只在
onBind中更新它们,则用户将看不到可见项目的更改,直到它们再次绑定(可能是onResume或滚动)。我省略了多余的代码,以免使问题复杂化。虽然我想找到一种比我和你提到的更清洁的方法。 -
您可以拨打
notifyDataSetChanged或notifyItemChanged手动拨打onBind -
@shayanpourvatan 谢谢,但我认为这不是一个好的解决方案。在文档中指出调用
notifyDataSetChanged()作为最后的结果。并且要使用其中一种更细粒度的方法,我需要知道哪些不是每次都绑定的,这不是一个常数。无论哪种方式,它都不能真正解决问题,它只是解决它。 -
我遇到了同样的问题,似乎我将 setHasStableIds 选项设置为 true。
标签: android android-recyclerview android-viewholder