支持库从 23.1.1 更新到 23.2.1 后,RecyclerView 适配器中的 notifyDataSetChange() 变慢
notifyDataSetChange() slow in RecyclerView adapter after support library update from 23.1.1 to 23.2.1
由于修复了一些错误,我不得不将支持库从 23.1.1 更新到 23.2.1。然而,我 运行 遇到了这个问题,即在此更新之后调用 notifyDataSetChange() 需要很多时间并且阻塞 UI。对于像 10-20 项这样的短列表,人们无法注意到差异,但是对于 400-500 项的列表,notifyDataSetChange() 需要 2-3 秒才能执行,并且它正在阻塞 UI。对于 23.1.1,我没有测量它需要多长时间,但从用户体验来看,更新是即时的,即使列表包含 500-600 个项目。
代码没有变化,只是将支持库从 23.1.1 升级到 23.2.1。
我尝试了所有 23.2.xx 和 23.3.xx 以及 23.4.xx 库,但都遇到了同样的问题。我没有尝试使用支持库 24.xx.xx,因为我需要使用 23 版本
当我从网络接收到 myItemList 时,我从 activity 异步更新适配器:
...
((MyRecyclerViewAdapter) mAdapter).updateList(myItemList);
...
在适配器中我有
public void updateList(List<MyItems> items) {
this.mDataset = items;
notifyDataSetChanged();
}
它在 23.1.1 上确实没有延迟和阻塞UI,正如我上面提到的,它在 23.2.1 和更高版本上变慢了。我想使用 23.2.1,因为引入了 RecylerView wrap_content 功能。
如有任何帮助,我们将不胜感激。
我的适配器还有:
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemName.setText(mDataset.get(position).getName());
holder.itemPoints.setText(String.valueOf(mDataset.get(position).getPointsNumber()));
}
....
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView itemName;
TextView itemPoints;
public ViewHolder(View rowView) {
super(rowView);
itemName = (TextView) rowView.findViewById(R.id.item_name);
itemPoints = (TextView) rowView.findViewById(R.id.item_points);
mView = rowView;
}
}
看来我的问题和这里描述的完全一样RecyclerView 23.2.x height=0dp causes onBind called for all items and scrollToPosition not working
如支持库 23.2+ 和更高版本中所述,如果设置 layout_height="0dp",将立即为列表中的所有项目调用 onBindViewHolder(),在我的例子中为 400- 的列表600 个项目造成了性能问题。
然而,与上面 link 中建议的解决方案相反,更新到支持库 23.3.0(或更高版本)并没有解决这个问题。
为了解决这个问题,我使用 layout_height="1dp" 而不是 layout_height="0dp" 尽管对我来说仍然不清楚为什么这种 hack 有效。或者更具体地说,为什么 layout_height="0dp" 无法正常工作。
我有一个类似的问题,我的 recyclerView 在更新其中的大量数据时(调用 notifyDataSetChanged 时)导致我的应用程序冻结几秒钟。
这是因为我的 recyclerView 嵌套在 NestedScrollView 中。当我删除布局中的 NestedScrollView 时,问题就解决了。
由于修复了一些错误,我不得不将支持库从 23.1.1 更新到 23.2.1。然而,我 运行 遇到了这个问题,即在此更新之后调用 notifyDataSetChange() 需要很多时间并且阻塞 UI。对于像 10-20 项这样的短列表,人们无法注意到差异,但是对于 400-500 项的列表,notifyDataSetChange() 需要 2-3 秒才能执行,并且它正在阻塞 UI。对于 23.1.1,我没有测量它需要多长时间,但从用户体验来看,更新是即时的,即使列表包含 500-600 个项目。
代码没有变化,只是将支持库从 23.1.1 升级到 23.2.1。
我尝试了所有 23.2.xx 和 23.3.xx 以及 23.4.xx 库,但都遇到了同样的问题。我没有尝试使用支持库 24.xx.xx,因为我需要使用 23 版本
当我从网络接收到 myItemList 时,我从 activity 异步更新适配器:
...
((MyRecyclerViewAdapter) mAdapter).updateList(myItemList);
...
在适配器中我有
public void updateList(List<MyItems> items) {
this.mDataset = items;
notifyDataSetChanged();
}
它在 23.1.1 上确实没有延迟和阻塞UI,正如我上面提到的,它在 23.2.1 和更高版本上变慢了。我想使用 23.2.1,因为引入了 RecylerView wrap_content 功能。
如有任何帮助,我们将不胜感激。
我的适配器还有:
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemName.setText(mDataset.get(position).getName());
holder.itemPoints.setText(String.valueOf(mDataset.get(position).getPointsNumber()));
}
....
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView itemName;
TextView itemPoints;
public ViewHolder(View rowView) {
super(rowView);
itemName = (TextView) rowView.findViewById(R.id.item_name);
itemPoints = (TextView) rowView.findViewById(R.id.item_points);
mView = rowView;
}
}
看来我的问题和这里描述的完全一样RecyclerView 23.2.x height=0dp causes onBind called for all items and scrollToPosition not working
如支持库 23.2+ 和更高版本中所述,如果设置 layout_height="0dp",将立即为列表中的所有项目调用 onBindViewHolder(),在我的例子中为 400- 的列表600 个项目造成了性能问题。
然而,与上面 link 中建议的解决方案相反,更新到支持库 23.3.0(或更高版本)并没有解决这个问题。
为了解决这个问题,我使用 layout_height="1dp" 而不是 layout_height="0dp" 尽管对我来说仍然不清楚为什么这种 hack 有效。或者更具体地说,为什么 layout_height="0dp" 无法正常工作。
我有一个类似的问题,我的 recyclerView 在更新其中的大量数据时(调用 notifyDataSetChanged 时)导致我的应用程序冻结几秒钟。 这是因为我的 recyclerView 嵌套在 NestedScrollView 中。当我删除布局中的 NestedScrollView 时,问题就解决了。