From 3616a412cbd620168fd87ce83978d83a9c0621c6 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 15 Sep 2009 13:50:37 -0700 Subject: [PATCH] Preserve ListView's pressed state when the adapter changes its content while the user is pressing an item. Change-Id: Id5ac804a4053951430d16cf0d87fc7b64c816717 --- core/java/android/widget/GridView.java | 17 ++++-- core/java/android/widget/ListView.java | 71 +++++++++++++++----------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index 9ec8347e46479..33e83c3eb7927 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -1148,9 +1148,12 @@ public class GridView extends AbsListView { if (sel != null) { positionSelector(sel); mSelectedTop = sel.getTop(); + } else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) { + View child = getChildAt(mMotionPosition - mFirstPosition); + positionSelector(child); } else { - mSelectedTop = 0; - mSelectorRect.setEmpty(); + mSelectedTop = 0; + mSelectorRect.setEmpty(); } mLayoutMode = LAYOUT_NORMAL; @@ -1231,8 +1234,12 @@ public class GridView extends AbsListView { private void setupChild(View child, int position, int y, boolean flow, int childrenLeft, boolean selected, boolean recycled, int where) { boolean isSelected = selected && shouldShowSelector(); - final boolean updateChildSelected = isSelected != child.isSelected(); + final int mode = mTouchMode; + final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && + mMotionPosition == position; + final boolean updateChildPressed = isPressed != child.isPressed(); + boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested(); // Respect layout params that are already in the view. Otherwise make @@ -1257,6 +1264,10 @@ public class GridView extends AbsListView { } } + if (updateChildPressed) { + child.setPressed(isPressed); + } + if (needToMeasure) { int childHeightSpec = ViewGroup.getChildMeasureSpec( MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 6316864c24d1a..41c926726bcab 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1542,37 +1542,42 @@ public class ListView extends AbsListView { recycleBin.scrapActiveViews(); if (sel != null) { - // the current selected item should get focus if items - // are focusable - if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) { - final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild && - focusLayoutRestoreView.requestFocus()) || sel.requestFocus(); - if (!focusWasTaken) { - // selected item didn't take focus, fine, but still want - // to make sure something else outside of the selected view - // has focus - final View focused = getFocusedChild(); - if (focused != null) { - focused.clearFocus(); - } - positionSelector(sel); - } else { - sel.setSelected(false); - mSelectorRect.setEmpty(); - } - } else { - positionSelector(sel); - } - mSelectedTop = sel.getTop(); + // the current selected item should get focus if items + // are focusable + if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) { + final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild && + focusLayoutRestoreView.requestFocus()) || sel.requestFocus(); + if (!focusWasTaken) { + // selected item didn't take focus, fine, but still want + // to make sure something else outside of the selected view + // has focus + final View focused = getFocusedChild(); + if (focused != null) { + focused.clearFocus(); + } + positionSelector(sel); + } else { + sel.setSelected(false); + mSelectorRect.setEmpty(); + } + } else { + positionSelector(sel); + } + mSelectedTop = sel.getTop(); } else { - mSelectedTop = 0; - mSelectorRect.setEmpty(); + if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) { + View child = getChildAt(mMotionPosition - mFirstPosition); + positionSelector(child); + } else { + mSelectedTop = 0; + mSelectorRect.setEmpty(); + } - // even if there is not selected position, we may need to restore - // focus (i.e. something focusable in touch mode) - if (hasFocus() && focusLayoutRestoreView != null) { - focusLayoutRestoreView.requestFocus(); - } + // even if there is not selected position, we may need to restore + // focus (i.e. something focusable in touch mode) + if (hasFocus() && focusLayoutRestoreView != null) { + focusLayoutRestoreView.requestFocus(); + } } // tell focus view we are done mucking with it, if it is still in @@ -1686,6 +1691,10 @@ public class ListView extends AbsListView { boolean selected, boolean recycled) { final boolean isSelected = selected && shouldShowSelector(); final boolean updateChildSelected = isSelected != child.isSelected(); + final int mode = mTouchMode; + final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && + mMotionPosition == position; + final boolean updateChildPressed = isPressed != child.isPressed(); final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested(); // Respect layout params that are already in the view. Otherwise make some up... @@ -1711,6 +1720,10 @@ public class ListView extends AbsListView { child.setSelected(isSelected); } + if (updateChildPressed) { + child.setPressed(isPressed); + } + if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) { if (child instanceof Checkable) { ((Checkable) child).setChecked(mCheckStates.get(position));