Rid*_*lly 5 android listadapter android-recyclerview
我正在使用ListAdapterRecyclerView,在某些情况下,应用程序变得非常慢——它会冻结 10 秒钟,并显示 1000 个项目的列表。
情况是,首先我提交了一个包含 1000 个项目的列表(首先按预期快速提交),然后我再次提交相同的列表,但排序方式不同。
通过调试,我终于发现, ListAdapter 触发了一个notifyItemRangeChanged(0, 999),所以基本上是完整的列表。我在其他地方(这里和这里)读到过,不应该这样做,因为它会使 RecyclerView 变慢——这显然是正确的——但是,我无法影响 ListAdapter 的行为。
有没有人有解决方案?我不想再次删除 ListAdapter,因为对于大多数其他用例,它既快速又方便,可以自动执行各种动画等。
编辑 - 一些代码
代码没有什么花哨的,基本上是这样的:
RecyclerView mListView;
EnryListAdapter mEntryListAdapter; // <-- extends ListAdapter<Entry, VH>
...
mEntryListAdapter = new EntryListAdapter();
mListView.setAdapter(mEntryListAdapter);
mListView.setLayoutManager(new LinearLayoutManager(this));
mListView.setHasFixedSize(true);
((DefaultItemAnimator) mListView.getItemAnimator()).setSupportsChangeAnimations(false);
List<Entry> entryList = getEntryList(); // <-- list with 1000 entries
mEntryListAdapter.submitList(entryList); // <-- first submit is fast
entryList = getDifferentlySortedEntryList(); // <-- list with same entries, sorted differently
mEntryListAdapter.submitList(entryList); // <-- freezes app for over 10 seconds
Run Code Online (Sandbox Code Playgroud)
最后我发现这是我自己的错误。
在我的实施中,DiffUtil.ItemCallback<Entry>#areContentsTheSame我进行了这样的检查:
oldItem.flags == newItem.flags
Run Code Online (Sandbox Code Playgroud)
其中Entry.flags是long第一个,但后来我将其更改为类的实例,但没有更改此比较。由于实例不是相同的对象,因此这种比较始终会产生结果false。替换为
ObjectsCompat.equals(oldItem.flags, newItem.flags)
Run Code Online (Sandbox Code Playgroud)
解决了这个问题。
| 归档时间: |
|
| 查看次数: |
1228 次 |
| 最近记录: |