diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 3d50fc896a5b5..2fa9484b6f4a1 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6075,8 +6075,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTransientStateCount = 0; Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " + "unmatched pair of setHasTransientState calls"); - } - if ((hasTransientState && mTransientStateCount == 1) || + } else if ((hasTransientState && mTransientStateCount == 1) || (!hasTransientState && mTransientStateCount == 0)) { // update flag if we've just incremented up from 0 or decremented down to 0 mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) | diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 396fd6821cde9..d659110b12660 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -6167,6 +6167,7 @@ public abstract class AbsListView extends AdapterView implements Te private ArrayList mSkippedScrap; private SparseArray mTransientStateViews; + private LongSparseArray mTransientStateViewsById; public void setViewTypeCount(int viewTypeCount) { if (viewTypeCount < 1) { @@ -6205,6 +6206,12 @@ public abstract class AbsListView extends AdapterView implements Te mTransientStateViews.valueAt(i).forceLayout(); } } + if (mTransientStateViewsById != null) { + final int count = mTransientStateViewsById.size(); + for (int i = 0; i < count; i++) { + mTransientStateViewsById.valueAt(i).forceLayout(); + } + } } public boolean shouldRecycleViewType(int viewType) { @@ -6234,6 +6241,9 @@ public abstract class AbsListView extends AdapterView implements Te if (mTransientStateViews != null) { mTransientStateViews.clear(); } + if (mTransientStateViewsById != null) { + mTransientStateViewsById.clear(); + } } /** @@ -6281,16 +6291,21 @@ public abstract class AbsListView extends AdapterView implements Te } View getTransientStateView(int position) { - if (mTransientStateViews == null) { - return null; + if (mAdapter != null && mAdapterHasStableIds && mTransientStateViewsById != null) { + long id = mAdapter.getItemId(position); + View result = mTransientStateViewsById.get(id); + mTransientStateViewsById.remove(id); + return result; } - final int index = mTransientStateViews.indexOfKey(position); - if (index < 0) { - return null; + if (mTransientStateViews != null) { + final int index = mTransientStateViews.indexOfKey(position); + if (index >= 0) { + View result = mTransientStateViews.valueAt(index); + mTransientStateViews.removeAt(index); + return result; + } } - final View result = mTransientStateViews.valueAt(index); - mTransientStateViews.removeAt(index); - return result; + return null; } /** @@ -6300,6 +6315,9 @@ public abstract class AbsListView extends AdapterView implements Te if (mTransientStateViews != null) { mTransientStateViews.clear(); } + if (mTransientStateViewsById != null) { + mTransientStateViewsById.clear(); + } } /** @@ -6342,11 +6360,18 @@ public abstract class AbsListView extends AdapterView implements Te mSkippedScrap.add(scrap); } if (scrapHasTransientState) { - if (mTransientStateViews == null) { - mTransientStateViews = new SparseArray(); - } scrap.dispatchStartTemporaryDetach(); - mTransientStateViews.put(position, scrap); + if (mAdapter != null && mAdapterHasStableIds) { + if (mTransientStateViewsById == null) { + mTransientStateViewsById = new LongSparseArray(); + } + mTransientStateViewsById.put(lp.itemId, scrap); + } else { + if (mTransientStateViews == null) { + mTransientStateViews = new SparseArray(); + } + mTransientStateViews.put(position, scrap); + } } return; } @@ -6405,10 +6430,18 @@ public abstract class AbsListView extends AdapterView implements Te removeDetachedView(victim, false); } if (scrapHasTransientState) { - if (mTransientStateViews == null) { - mTransientStateViews = new SparseArray(); + if (mAdapter != null && mAdapterHasStableIds) { + if (mTransientStateViewsById == null) { + mTransientStateViewsById = new LongSparseArray(); + } + long id = mAdapter.getItemId(mFirstActivePosition + i); + mTransientStateViewsById.put(id, victim); + } else { + if (mTransientStateViews == null) { + mTransientStateViews = new SparseArray(); + } + mTransientStateViews.put(mFirstActivePosition + i, victim); } - mTransientStateViews.put(mFirstActivePosition + i, victim); } continue; } @@ -6457,6 +6490,15 @@ public abstract class AbsListView extends AdapterView implements Te } } } + if (mTransientStateViewsById != null) { + for (int i = 0; i < mTransientStateViewsById.size(); i++) { + final View v = mTransientStateViewsById.valueAt(i); + if (!v.hasTransientState()) { + mTransientStateViewsById.removeAt(i); + i--; + } + } + } } /**