Merge "RecyclerView should recycle views on adapter change." into lmp-preview-dev
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index bb9a613..1026331 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -252,6 +252,18 @@
if (mAdapter != null) {
mAdapter.unregisterAdapterDataObserver(mObserver);
}
+ // end all running animations
+ if (mItemAnimator != null) {
+ mItemAnimator.endAnimations();
+ }
+ // Since animations are ended, mLayout.children should be equal to recyclerView.children.
+ // This may not be true if item animator's end does not work as expected. (e.g. not release
+ // children instantly). It is safer to use mLayout's child count.
+ if (mLayout != null) {
+ mLayout.removeAndRecycleAllViews(mRecycler);
+ mLayout.removeAndRecycleScrapInt(mRecycler, true);
+ }
+
final Adapter oldAdapter = mAdapter;
mAdapter = adapter;
if (adapter != null) {
@@ -3477,13 +3489,15 @@
final Adapter adapter = mRecyclerView.getAdapter();
// Only remove non-animating views
final int childCount = mRecyclerView.getChildCount() - mRecyclerView.mNumAnimatingViews;
- if (adapter != null) {
- for (int i = 0; i < childCount; i++) {
- final View child = mRecyclerView.getChildAt(i);
+
+ for (int i = 0; i < childCount; i++) {
+ final View child = mRecyclerView.getChildAt(i);
+ if (adapter != null) {
adapter.onViewDetachedFromWindow(getChildViewHolderInt(child));
- mRecyclerView.onChildDetachedFromWindow(child);
}
+ mRecyclerView.onChildDetachedFromWindow(child);
}
+
for (int i = childCount - 1; i >= 0; i--) {
mRecyclerView.removeViewAt(i);
if (mRecyclerView.mAnimatingViewIndex >= 0) {
@@ -4445,6 +4459,12 @@
mSmoothScroller = null;
}
}
+
+ void removeAndRecycleAllViews(Recycler recycler) {
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ removeAndRecycleViewAt(i, recycler);
+ }
+ }
}
/**