androidx.RecyclerView ListAdapter 很慢

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)

Rid*_*lly 3

最后我发现这是我自己的错误

在我的实施中,DiffUtil.ItemCallback<Entry>#areContentsTheSame我进行了这样的检查:

oldItem.flags == newItem.flags
Run Code Online (Sandbox Code Playgroud)

其中Entry.flagslong第一个,但后来我将其更改为类的实例,但没有更改此比较。由于实例不是相同的对象,因此这种比较始终会产生结果false。替换为

ObjectsCompat.equals(oldItem.flags, newItem.flags)
Run Code Online (Sandbox Code Playgroud)

解决了这个问题。