Preserve ListView's pressed state when the adapter changes its content while the user is pressing an item.

Change-Id: Id5ac804a4053951430d16cf0d87fc7b64c816717
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 9ec8347..33e83c3 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1148,9 +1148,12 @@
             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 @@
     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 @@
             }
         }
 
+        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 6316864..41c9267 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1542,37 +1542,42 @@
             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 @@
             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 @@
             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));