Loading core/java/android/view/View.java +47 −0 Original line number Diff line number Diff line Loading @@ -1759,6 +1759,16 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal static final int LAYOUT_DIRECTION_RESOLVED = 0x00000008; /** * Indicates that the view is tracking some sort of transient state * that the app should not need to be aware of, but that the framework * should take special care to preserve. * * @hide */ static final int HAS_TRANSIENT_STATE = 0x00000010; /* End of masks for mPrivateFlags2 */ static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED; Loading Loading @@ -4888,6 +4898,43 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL); } /** * Indicates whether the view is currently tracking transient state that the * app should not need to concern itself with saving and restoring, but that * the framework should take special note to preserve when possible. * * @return true if the view has transient state * * @hide */ @ViewDebug.ExportedProperty(category = "layout") public boolean hasTransientState() { return (mPrivateFlags2 & HAS_TRANSIENT_STATE) == HAS_TRANSIENT_STATE; } /** * Set whether this view is currently tracking transient state that the * framework should attempt to preserve when possible. * * @param hasTransientState true if this view has transient state * * @hide */ public void setHasTransientState(boolean hasTransientState) { if (hasTransientState() == hasTransientState) return; mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) | (hasTransientState ? HAS_TRANSIENT_STATE : 0); if (mParent != null) { try { mParent.childHasTransientStateChanged(this, hasTransientState); } catch (AbstractMethodError e) { Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); } } } /** * If this view doesn't do any drawing on its own, set this flag to * allow further optimizations. By default, this flag is not set on Loading core/java/android/view/ViewGroup.java +57 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import java.util.HashSet; * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges */ public abstract class ViewGroup extends View implements ViewParent, ViewManager { private static final String TAG = "ViewGroup"; private static final boolean DBG = false; Loading Loading @@ -375,6 +376,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @ViewDebug.ExportedProperty(category = "drawing") boolean mDrawLayers = true; // Indicates how many of this container's child subtrees contain transient state @ViewDebug.ExportedProperty(category = "layout") private int mChildCountWithTransientState = 0; public ViewGroup(Context context) { super(context); initViewGroup(); Loading Loading @@ -652,6 +657,38 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; } /** * Called when a child view has changed whether or not it is tracking transient state. * * @hide */ public void childHasTransientStateChanged(View child, boolean childHasTransientState) { final boolean oldHasTransientState = hasTransientState(); if (childHasTransientState) { mChildCountWithTransientState++; } else { mChildCountWithTransientState--; } final boolean newHasTransientState = hasTransientState(); if (mParent != null && oldHasTransientState != newHasTransientState) { try { mParent.childHasTransientStateChanged(this, newHasTransientState); } catch (AbstractMethodError e) { Log.e(TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); } } } /** * @hide */ @Override public boolean hasTransientState() { return mChildCountWithTransientState > 0 || super.hasTransientState(); } /** * {@inheritDoc} */ Loading Loading @@ -3099,6 +3136,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) { mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE; } if (child.hasTransientState()) { childHasTransientStateChanged(child, true); } } private void addInArray(View child, int index) { Loading Loading @@ -3295,6 +3336,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } onViewRemoved(view); needGlobalAttributesUpdate(false); Loading Loading @@ -3366,6 +3411,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } needGlobalAttributesUpdate(false); onViewRemoved(view); Loading Loading @@ -3431,6 +3480,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } onViewRemoved(view); view.mParent = null; Loading Loading @@ -3471,6 +3524,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.dispatchDetachedFromWindow(); } if (child.hasTransientState()) { childHasTransientStateChanged(child, false); } onViewRemoved(child); } Loading core/java/android/view/ViewParent.java +10 −0 Original line number Diff line number Diff line Loading @@ -261,4 +261,14 @@ public interface ViewParent { * @return True if the event was sent. */ public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event); /** * Called when a child view now has or no longer is tracking transient state. * * @param child Child view whose state has changed * @param hasTransientState true if this child has transient state * * @hide */ public void childHasTransientStateChanged(View child, boolean hasTransientState); } core/java/android/view/ViewRootImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -4144,6 +4144,10 @@ public final class ViewRootImpl implements ViewParent, return scrollToRectOrFocus(rectangle, immediate); } public void childHasTransientStateChanged(View child, boolean hasTransientState) { // Do nothing. } class TakenSurfaceHolder extends BaseSurfaceHolder { @Override public boolean onAllowLockCanvas() { Loading core/java/android/widget/AbsListView.java +108 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.StateSet; import android.view.ActionMode; Loading Loading @@ -87,6 +88,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te ViewTreeObserver.OnTouchModeChangeListener, RemoteViewsAdapter.RemoteAdapterConnectionCallback { private static final String TAG = "AbsListView"; /** * Disables the transcript mode. * Loading Loading @@ -262,6 +265,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ private RemoteViewsAdapter mRemoteAdapter; /** * If mAdapter != null, whenever this is true the adapter has stable IDs. */ boolean mAdapterHasStableIds; /** * This flag indicates the a full notify is required when the RemoteViewsAdapter connects */ Loading Loading @@ -812,7 +820,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public void setAdapter(ListAdapter adapter) { if (adapter != null) { if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() && mAdapterHasStableIds = mAdapter.hasStableIds(); if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds && mCheckedIdStates == null) { mCheckedIdStates = new LongSparseArray<Integer>(); } Loading Loading @@ -2011,6 +2020,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te isScrap[0] = false; View scrapView; scrapView = mRecycler.getTransientStateView(position); if (scrapView != null) { return scrapView; } scrapView = mRecycler.getScrapView(position); View child; Loading @@ -2021,6 +2035,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } child = mAdapter.getView(position, scrapView, this); if (mAdapterHasStableIds) { LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = (LayoutParams) generateDefaultLayoutParams(); } lp.itemId = mAdapter.getItemId(position); } if (ViewDebug.TRACE_RECYCLER) { ViewDebug.trace(child, ViewDebug.RecyclerTraceType.BIND_VIEW, Loading Loading @@ -4543,7 +4564,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (count > 0) { detachViewsFromParent(start, count); mRecycler.removeSkippedScrap(); } offsetChildrenTopAndBottom(incrementalDeltaY); if (down) { Loading Loading @@ -4853,6 +4876,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te confirmCheckedPositionsById(); } // TODO: In the future we can recycle these views based on stable ID instead. mRecycler.clearTransientStateViews(); if (count > 0) { int newPos; int selectablePos; Loading Loading @@ -5735,6 +5761,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ int scrappedFromPosition; /** * The ID the view represents */ long itemId = -1; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); } Loading Loading @@ -5807,6 +5838,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private ArrayList<View> mCurrentScrap; private ArrayList<View> mSkippedScrap; private SparseArray<View> mTransientStateViews; public void setViewTypeCount(int viewTypeCount) { if (viewTypeCount < 1) { throw new IllegalArgumentException("Can't have a viewTypeCount < 1"); Loading Loading @@ -5838,6 +5873,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } if (mTransientStateViews != null) { final int count = mTransientStateViews.size(); for (int i = 0; i < count; i++) { mTransientStateViews.valueAt(i).forceLayout(); } } } public boolean shouldRecycleViewType(int viewType) { Loading @@ -5864,6 +5905,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } if (mTransientStateViews != null) { mTransientStateViews.clear(); } } /** Loading Loading @@ -5910,6 +5954,28 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return null; } View getTransientStateView(int position) { if (mTransientStateViews == null) { return null; } final int index = mTransientStateViews.indexOfKey(position); if (index < 0) { return null; } final View result = mTransientStateViews.valueAt(index); mTransientStateViews.removeAt(index); return result; } /** * Dump any currently saved views with transient state. */ void clearTransientStateViews() { if (mTransientStateViews != null) { mTransientStateViews.clear(); } } /** * @return A view from the ScrapViews collection. These are unordered. */ Loading @@ -5926,7 +5992,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** * Put a view into the ScapViews list. These views are unordered. * Put a view into the ScrapViews list. These views are unordered. * * @param scrap The view to add */ Loading @@ -5936,23 +6002,32 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return; } lp.scrappedFromPosition = position; // Don't put header or footer views or views that should be ignored // into the scrap heap int viewType = lp.viewType; if (!shouldRecycleViewType(viewType)) { if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { removeDetachedView(scrap, false); final boolean scrapHasTransientState = scrap.hasTransientState(); if (!shouldRecycleViewType(viewType) || scrapHasTransientState) { if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) { if (mSkippedScrap == null) { mSkippedScrap = new ArrayList<View>(); } mSkippedScrap.add(scrap); } if (scrapHasTransientState) { if (mTransientStateViews == null) { mTransientStateViews = new SparseArray<View>(); } mTransientStateViews.put(position, scrap); } return; } lp.scrappedFromPosition = position; if (mViewTypeCount == 1) { scrap.dispatchStartTemporaryDetach(); if (mViewTypeCount == 1) { mCurrentScrap.add(scrap); } else { scrap.dispatchStartTemporaryDetach(); mScrapViews[viewType].add(scrap); } Loading @@ -5961,6 +6036,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } /** * Finish the removal of any views that skipped the scrap heap. */ void removeSkippedScrap() { if (mSkippedScrap == null) { return; } final int count = mSkippedScrap.size(); for (int i = 0; i < count; i++) { removeDetachedView(mSkippedScrap.get(i), false); } mSkippedScrap.clear(); } /** * Move all views remaining in mActiveViews to mScrapViews. */ Loading @@ -5980,11 +6069,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te activeViews[i] = null; if (!shouldRecycleViewType(whichScrap)) { final boolean scrapHasTransientState = victim.hasTransientState(); if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) { // Do not move views that should be ignored if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) { removeDetachedView(victim, false); } if (scrapHasTransientState) { if (mTransientStateViews == null) { mTransientStateViews = new SparseArray<View>(); } mTransientStateViews.put(mFirstActivePosition + i, victim); } continue; } Loading Loading
core/java/android/view/View.java +47 −0 Original line number Diff line number Diff line Loading @@ -1759,6 +1759,16 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal static final int LAYOUT_DIRECTION_RESOLVED = 0x00000008; /** * Indicates that the view is tracking some sort of transient state * that the app should not need to be aware of, but that the framework * should take special care to preserve. * * @hide */ static final int HAS_TRANSIENT_STATE = 0x00000010; /* End of masks for mPrivateFlags2 */ static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED; Loading Loading @@ -4888,6 +4898,43 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL); } /** * Indicates whether the view is currently tracking transient state that the * app should not need to concern itself with saving and restoring, but that * the framework should take special note to preserve when possible. * * @return true if the view has transient state * * @hide */ @ViewDebug.ExportedProperty(category = "layout") public boolean hasTransientState() { return (mPrivateFlags2 & HAS_TRANSIENT_STATE) == HAS_TRANSIENT_STATE; } /** * Set whether this view is currently tracking transient state that the * framework should attempt to preserve when possible. * * @param hasTransientState true if this view has transient state * * @hide */ public void setHasTransientState(boolean hasTransientState) { if (hasTransientState() == hasTransientState) return; mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) | (hasTransientState ? HAS_TRANSIENT_STATE : 0); if (mParent != null) { try { mParent.childHasTransientStateChanged(this, hasTransientState); } catch (AbstractMethodError e) { Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); } } } /** * If this view doesn't do any drawing on its own, set this flag to * allow further optimizations. By default, this flag is not set on Loading
core/java/android/view/ViewGroup.java +57 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import java.util.HashSet; * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges */ public abstract class ViewGroup extends View implements ViewParent, ViewManager { private static final String TAG = "ViewGroup"; private static final boolean DBG = false; Loading Loading @@ -375,6 +376,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @ViewDebug.ExportedProperty(category = "drawing") boolean mDrawLayers = true; // Indicates how many of this container's child subtrees contain transient state @ViewDebug.ExportedProperty(category = "layout") private int mChildCountWithTransientState = 0; public ViewGroup(Context context) { super(context); initViewGroup(); Loading Loading @@ -652,6 +657,38 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; } /** * Called when a child view has changed whether or not it is tracking transient state. * * @hide */ public void childHasTransientStateChanged(View child, boolean childHasTransientState) { final boolean oldHasTransientState = hasTransientState(); if (childHasTransientState) { mChildCountWithTransientState++; } else { mChildCountWithTransientState--; } final boolean newHasTransientState = hasTransientState(); if (mParent != null && oldHasTransientState != newHasTransientState) { try { mParent.childHasTransientStateChanged(this, newHasTransientState); } catch (AbstractMethodError e) { Log.e(TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); } } } /** * @hide */ @Override public boolean hasTransientState() { return mChildCountWithTransientState > 0 || super.hasTransientState(); } /** * {@inheritDoc} */ Loading Loading @@ -3099,6 +3136,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) { mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE; } if (child.hasTransientState()) { childHasTransientStateChanged(child, true); } } private void addInArray(View child, int index) { Loading Loading @@ -3295,6 +3336,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } onViewRemoved(view); needGlobalAttributesUpdate(false); Loading Loading @@ -3366,6 +3411,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } needGlobalAttributesUpdate(false); onViewRemoved(view); Loading Loading @@ -3431,6 +3480,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager view.dispatchDetachedFromWindow(); } if (view.hasTransientState()) { childHasTransientStateChanged(view, false); } onViewRemoved(view); view.mParent = null; Loading Loading @@ -3471,6 +3524,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.dispatchDetachedFromWindow(); } if (child.hasTransientState()) { childHasTransientStateChanged(child, false); } onViewRemoved(child); } Loading
core/java/android/view/ViewParent.java +10 −0 Original line number Diff line number Diff line Loading @@ -261,4 +261,14 @@ public interface ViewParent { * @return True if the event was sent. */ public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event); /** * Called when a child view now has or no longer is tracking transient state. * * @param child Child view whose state has changed * @param hasTransientState true if this child has transient state * * @hide */ public void childHasTransientStateChanged(View child, boolean hasTransientState); }
core/java/android/view/ViewRootImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -4144,6 +4144,10 @@ public final class ViewRootImpl implements ViewParent, return scrollToRectOrFocus(rectangle, immediate); } public void childHasTransientStateChanged(View child, boolean hasTransientState) { // Do nothing. } class TakenSurfaceHolder extends BaseSurfaceHolder { @Override public boolean onAllowLockCanvas() { Loading
core/java/android/widget/AbsListView.java +108 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.StateSet; import android.view.ActionMode; Loading Loading @@ -87,6 +88,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te ViewTreeObserver.OnTouchModeChangeListener, RemoteViewsAdapter.RemoteAdapterConnectionCallback { private static final String TAG = "AbsListView"; /** * Disables the transcript mode. * Loading Loading @@ -262,6 +265,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ private RemoteViewsAdapter mRemoteAdapter; /** * If mAdapter != null, whenever this is true the adapter has stable IDs. */ boolean mAdapterHasStableIds; /** * This flag indicates the a full notify is required when the RemoteViewsAdapter connects */ Loading Loading @@ -812,7 +820,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public void setAdapter(ListAdapter adapter) { if (adapter != null) { if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() && mAdapterHasStableIds = mAdapter.hasStableIds(); if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds && mCheckedIdStates == null) { mCheckedIdStates = new LongSparseArray<Integer>(); } Loading Loading @@ -2011,6 +2020,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te isScrap[0] = false; View scrapView; scrapView = mRecycler.getTransientStateView(position); if (scrapView != null) { return scrapView; } scrapView = mRecycler.getScrapView(position); View child; Loading @@ -2021,6 +2035,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } child = mAdapter.getView(position, scrapView, this); if (mAdapterHasStableIds) { LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = (LayoutParams) generateDefaultLayoutParams(); } lp.itemId = mAdapter.getItemId(position); } if (ViewDebug.TRACE_RECYCLER) { ViewDebug.trace(child, ViewDebug.RecyclerTraceType.BIND_VIEW, Loading Loading @@ -4543,7 +4564,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (count > 0) { detachViewsFromParent(start, count); mRecycler.removeSkippedScrap(); } offsetChildrenTopAndBottom(incrementalDeltaY); if (down) { Loading Loading @@ -4853,6 +4876,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te confirmCheckedPositionsById(); } // TODO: In the future we can recycle these views based on stable ID instead. mRecycler.clearTransientStateViews(); if (count > 0) { int newPos; int selectablePos; Loading Loading @@ -5735,6 +5761,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ int scrappedFromPosition; /** * The ID the view represents */ long itemId = -1; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); } Loading Loading @@ -5807,6 +5838,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private ArrayList<View> mCurrentScrap; private ArrayList<View> mSkippedScrap; private SparseArray<View> mTransientStateViews; public void setViewTypeCount(int viewTypeCount) { if (viewTypeCount < 1) { throw new IllegalArgumentException("Can't have a viewTypeCount < 1"); Loading Loading @@ -5838,6 +5873,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } if (mTransientStateViews != null) { final int count = mTransientStateViews.size(); for (int i = 0; i < count; i++) { mTransientStateViews.valueAt(i).forceLayout(); } } } public boolean shouldRecycleViewType(int viewType) { Loading @@ -5864,6 +5905,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } if (mTransientStateViews != null) { mTransientStateViews.clear(); } } /** Loading Loading @@ -5910,6 +5954,28 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return null; } View getTransientStateView(int position) { if (mTransientStateViews == null) { return null; } final int index = mTransientStateViews.indexOfKey(position); if (index < 0) { return null; } final View result = mTransientStateViews.valueAt(index); mTransientStateViews.removeAt(index); return result; } /** * Dump any currently saved views with transient state. */ void clearTransientStateViews() { if (mTransientStateViews != null) { mTransientStateViews.clear(); } } /** * @return A view from the ScrapViews collection. These are unordered. */ Loading @@ -5926,7 +5992,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** * Put a view into the ScapViews list. These views are unordered. * Put a view into the ScrapViews list. These views are unordered. * * @param scrap The view to add */ Loading @@ -5936,23 +6002,32 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return; } lp.scrappedFromPosition = position; // Don't put header or footer views or views that should be ignored // into the scrap heap int viewType = lp.viewType; if (!shouldRecycleViewType(viewType)) { if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { removeDetachedView(scrap, false); final boolean scrapHasTransientState = scrap.hasTransientState(); if (!shouldRecycleViewType(viewType) || scrapHasTransientState) { if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) { if (mSkippedScrap == null) { mSkippedScrap = new ArrayList<View>(); } mSkippedScrap.add(scrap); } if (scrapHasTransientState) { if (mTransientStateViews == null) { mTransientStateViews = new SparseArray<View>(); } mTransientStateViews.put(position, scrap); } return; } lp.scrappedFromPosition = position; if (mViewTypeCount == 1) { scrap.dispatchStartTemporaryDetach(); if (mViewTypeCount == 1) { mCurrentScrap.add(scrap); } else { scrap.dispatchStartTemporaryDetach(); mScrapViews[viewType].add(scrap); } Loading @@ -5961,6 +6036,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } /** * Finish the removal of any views that skipped the scrap heap. */ void removeSkippedScrap() { if (mSkippedScrap == null) { return; } final int count = mSkippedScrap.size(); for (int i = 0; i < count; i++) { removeDetachedView(mSkippedScrap.get(i), false); } mSkippedScrap.clear(); } /** * Move all views remaining in mActiveViews to mScrapViews. */ Loading @@ -5980,11 +6069,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te activeViews[i] = null; if (!shouldRecycleViewType(whichScrap)) { final boolean scrapHasTransientState = victim.hasTransientState(); if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) { // Do not move views that should be ignored if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) { removeDetachedView(victim, false); } if (scrapHasTransientState) { if (mTransientStateViews == null) { mTransientStateViews = new SparseArray<View>(); } mTransientStateViews.put(mFirstActivePosition + i, victim); } continue; } Loading