踩坑android
<classPath>
<root type="composite">
<root url="jar://$USER_HOME$/Library/Android/sdk/platforms/android-27/android.jar!/" type="simple" />
<root url="file://$USER_HOME$/Library/Android/sdk/platforms/android-27/data/res" type="simple" />
</root>
</classPath>
複製代碼
RecyclerView已經提供的局部刷新功能git
Adapter.notifyItemChanged(int)
Adapter.notifyItemInserted(int)
Adapter.notifyItemRangeChanged(int, int)
Adapter.notifyItemRangeInserted(int, int)
Adapter.notifyItemRangeRemoved(int, int)
複製代碼
可見,局部刷新,須要指定Item的Position。因此若是更新的是整個列表的數據,則須要開發者計算須要刷新的Position。 不然使用Adapter.notifyDataSetChanged();會致使全部Item都刷新,即便新列表數據大部分和當前RecyclerView中展現的數據相同。github
Google提供了新的解決方案bash
存在的問題ide
* calculateDiff在主線程,若是新舊數據差異很大,耗時長,會致使ANR
* 最後須要調用dispatchUpdatesTo比較麻煩
複製代碼
解決辦法gradle
mListDiffer.submitList中使用線程進行的比較,使用主線程更新UIui
源碼以下url
public void submitList(final List<T> newList) {
if (newList == mList) {
// nothing to do
return;
}
// incrementing generation means any currently-running diffs are discarded when they finish
final int runGeneration = ++mMaxScheduledGeneration;
if (newList == null) {
//noinspection ConstantConditions
mUpdateCallback.onRemoved(0, mList.size());
mList = null;
mReadOnlyList = Collections.emptyList();
return;
}
if (mList == null) {
// fast simple first insert
mUpdateCallback.onInserted(0, newList.size());
mList = newList;
mReadOnlyList = Collections.unmodifiableList(newList);
return;
}
final List<T> oldList = mList;
mConfig.getBackgroundThreadExecutor().execute(new Runnable() {
@Override
public void run() {
final DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return oldList.size();
}
@Override
public int getNewListSize() {
return newList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return mConfig.getDiffCallback().areItemsTheSame(
oldList.get(oldItemPosition), newList.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return mConfig.getDiffCallback().areContentsTheSame(
oldList.get(oldItemPosition), newList.get(newItemPosition));
}
});
mConfig.getMainThreadExecutor().execute(new Runnable() {
@Override
public void run() {
if (mMaxScheduledGeneration == runGeneration) {
latchList(newList, result);
}
}
});
}
});
}
複製代碼
例子: github.com/outman8511/…spa