summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/util/StateSet.java1
-rw-r--r--core/java/android/view/View.java10
-rw-r--r--core/java/android/widget/AbsListView.java123
-rw-r--r--core/java/android/widget/AdapterView.java1
-rw-r--r--core/java/android/widget/GridView.java13
-rw-r--r--core/java/android/widget/ListView.java29
6 files changed, 128 insertions, 49 deletions
diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java
index f3d8159..21d8e45 100644
--- a/core/java/android/util/StateSet.java
+++ b/core/java/android/util/StateSet.java
@@ -38,6 +38,7 @@ import com.android.internal.R;
public class StateSet {
public static final int[] WILD_CARD = new int[0];
+ public static final int[] NOTHING = new int[] { 0 };
/**
* Return whether the stateSetOrSpec is matched by all StateSets.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fd7f4a4..340678d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8620,6 +8620,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
/**
+ * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
+ * on all Drawable objects associated with this view.
+ */
+ public void jumpDrawablesToCurrentState() {
+ if (mBGDrawable != null) {
+ mBGDrawable.jumpToCurrentState();
+ }
+ }
+
+ /**
* Sets the background color for this view.
* @param color the color of the background
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4e90ecd..7629673 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseBooleanArray;
+import android.util.StateSet;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -254,6 +255,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
Drawable mSelector;
/**
+ * Set to true if we would like to have the selector showing itself.
+ * We still need to draw and position it even if this is false.
+ */
+ boolean mSelectorShowing;
+
+ /**
+ * The current position of the selector in the list.
+ */
+ int mSelectorPosition = INVALID_POSITION;
+
+ /**
* Defines the selector's location and dimension at drawing time
*/
Rect mSelectorRect = new Rect();
@@ -1324,6 +1336,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setSelectedPositionInt(INVALID_POSITION);
// Do this before setting mNeedSync since setNextSelectedPosition looks at mNeedSync
setNextSelectedPositionInt(INVALID_POSITION);
+ mSelectorPosition = INVALID_POSITION;
mNeedSync = true;
mSyncRowId = ss.firstId;
mSyncPosition = ss.position;
@@ -1416,6 +1429,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
+ mSelectorShowing = false;
+ mSelectorPosition = INVALID_POSITION;
mSelectorRect.setEmpty();
invalidate();
}
@@ -1708,7 +1723,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
if (child != scrapView) {
- mRecycler.addScrapView(scrapView);
+ mRecycler.addScrapView(scrapView, position);
if (mCacheColorHint != 0) {
child.setDrawingCacheBackgroundColor(mCacheColorHint);
}
@@ -1734,7 +1749,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return child;
}
- void positionSelector(View sel) {
+ void positionSelector(int position, View sel) {
+ if (position != INVALID_POSITION) {
+ mSelectorPosition = position;
+ }
+
final Rect selectorRect = mSelectorRect;
selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom());
positionSelector(selectorRect.left, selectorRect.top, selectorRect.right,
@@ -1743,7 +1762,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final boolean isChildViewEnabled = mIsChildViewEnabled;
if (sel.isEnabled() != isChildViewEnabled) {
mIsChildViewEnabled = !isChildViewEnabled;
- refreshDrawableState();
+ if (mSelectorShowing) {
+ refreshDrawableState();
+ }
}
}
@@ -1822,7 +1843,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
private void drawSelector(Canvas canvas) {
- if (shouldShowSelector() && mSelectorRect != null && !mSelectorRect.isEmpty()) {
+ if (!mSelectorRect.isEmpty()) {
final Drawable selector = mSelector;
selector.setBounds(mSelectorRect);
selector.draw(canvas);
@@ -1866,7 +1887,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mSelectionRightPadding = padding.right;
mSelectionBottomPadding = padding.bottom;
sel.setCallback(this);
- sel.setState(getDrawableState());
+ updateSelectorState();
}
/**
@@ -1891,7 +1912,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
Drawable selector = mSelector;
Rect selectorRect = mSelectorRect;
if (selector != null && (isFocused() || touchModeDrawsInPressedState())
- && selectorRect != null && !selectorRect.isEmpty()) {
+ && !selectorRect.isEmpty()) {
final View v = getChildAt(mSelectedPosition - mFirstPosition);
@@ -1926,12 +1947,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mScrollDown = down;
}
+ void updateSelectorState() {
+ if (mSelector != null) {
+ if (shouldShowSelector()) {
+ mSelector.setState(getDrawableState());
+ } else {
+ mSelector.setState(StateSet.NOTHING);
+ }
+ }
+ }
+
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
- if (mSelector != null) {
- mSelector.setState(getDrawableState());
- }
+ updateSelectorState();
}
@Override
@@ -2141,7 +2170,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
} else {
mTouchMode = TOUCH_MODE_DONE_WAITING;
}
-
}
}
}
@@ -2316,10 +2344,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mLayoutMode = LAYOUT_NORMAL;
if (!mDataChanged) {
- layoutChildren();
child.setPressed(true);
- positionSelector(child);
setPressed(true);
+ layoutChildren();
+ positionSelector(mMotionPosition, child);
final int longPressTimeout = ViewConfiguration.getLongPressTimeout();
final boolean longClickable = isLongClickable();
@@ -2566,7 +2594,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setSelectedPositionInt(mMotionPosition);
layoutChildren();
child.setPressed(true);
- positionSelector(child);
+ positionSelector(mMotionPosition, child);
setPressed(true);
if (mSelector != null) {
Drawable d = mSelector.getCurrent();
@@ -2576,16 +2604,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
postDelayed(new Runnable() {
public void run() {
+ mTouchMode = TOUCH_MODE_REST;
child.setPressed(false);
setPressed(false);
if (!mDataChanged) {
post(performClick);
}
- mTouchMode = TOUCH_MODE_REST;
}
}, ViewConfiguration.getPressedStateDuration());
} else {
mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
}
return true;
} else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
@@ -2593,6 +2622,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
break;
case TOUCH_MODE_SCROLL:
final int childCount = getChildCount();
@@ -3507,7 +3537,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
count++;
int position = firstPosition + i;
if (position >= headerViewsCount && position < footerViewsStart) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, position);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(child,
@@ -3528,7 +3558,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
count++;
int position = firstPosition + i;
if (position >= headerViewsCount && position < footerViewsStart) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, position);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(child,
@@ -3563,8 +3593,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (!inTouchMode && mSelectedPosition != INVALID_POSITION) {
final int childIndex = mSelectedPosition - mFirstPosition;
if (childIndex >= 0 && childIndex < getChildCount()) {
- positionSelector(getChildAt(childIndex));
+ positionSelector(mSelectedPosition, getChildAt(childIndex));
+ }
+ } else if (mSelectorPosition != INVALID_POSITION) {
+ final int childIndex = mSelectorPosition - mFirstPosition;
+ if (childIndex >= 0 && childIndex < getChildCount()) {
+ positionSelector(INVALID_POSITION, getChildAt(childIndex));
}
+ } else {
+ mSelectorRect.setEmpty();
}
mBlockLayoutRequests = false;
@@ -3616,7 +3653,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
- mSelectorRect.setEmpty();
+ mSelectorShowing = false;
}
}
@@ -3876,6 +3913,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
+ mSelectorPosition = INVALID_POSITION;
checkSelectionChanged();
}
@@ -4562,6 +4600,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@ViewDebug.ExportedProperty(category = "list")
boolean forceAdd;
+ /**
+ * The position the view was removed from when pulled out of the
+ * scrap heap.
+ * @hide
+ */
+ int scrappedFromPosition;
+
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
@@ -4741,23 +4786,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @return A view from the ScrapViews collection. These are unordered.
*/
View getScrapView(int position) {
- ArrayList<View> scrapViews;
if (mViewTypeCount == 1) {
- scrapViews = mCurrentScrap;
- int size = scrapViews.size();
- if (size > 0) {
- return scrapViews.remove(size - 1);
- } else {
- return null;
- }
+ return retrieveFromScrap(mCurrentScrap, position);
} else {
int whichScrap = mAdapter.getItemViewType(position);
if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
- scrapViews = mScrapViews[whichScrap];
- int size = scrapViews.size();
- if (size > 0) {
- return scrapViews.remove(size - 1);
- }
+ return retrieveFromScrap(mScrapViews[whichScrap], position);
}
}
return null;
@@ -4768,7 +4802,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*
* @param scrap The view to add
*/
- void addScrapView(View scrap) {
+ void addScrapView(View scrap, int position) {
AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
if (lp == null) {
return;
@@ -4784,6 +4818,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return;
}
+ lp.scrappedFromPosition = position;
+
if (mViewTypeCount == 1) {
scrap.dispatchStartTemporaryDetach();
mCurrentScrap.add(scrap);
@@ -4810,7 +4846,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
for (int i = count - 1; i >= 0; i--) {
final View victim = activeViews[i];
if (victim != null) {
- int whichScrap = ((AbsListView.LayoutParams) victim.getLayoutParams()).viewType;
+ final AbsListView.LayoutParams lp
+ = (AbsListView.LayoutParams) victim.getLayoutParams();
+ int whichScrap = lp.viewType;
activeViews[i] = null;
@@ -4826,6 +4864,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
scrapViews = mScrapViews[whichScrap];
}
victim.dispatchStartTemporaryDetach();
+ lp.scrappedFromPosition = mFirstActivePosition + i;
scrapViews.add(victim);
if (hasListener) {
@@ -4911,4 +4950,22 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
+
+ static View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
+ int size = scrapViews.size();
+ if (size > 0) {
+ // See if we still have a view for this position.
+ for (int i=0; i<size; i++) {
+ View view = scrapViews.get(i);
+ if (((AbsListView.LayoutParams)view.getLayoutParams())
+ .scrappedFromPosition == position) {
+ scrapViews.remove(i);
+ return view;
+ }
+ }
+ return scrapViews.remove(size - 1);
+ } else {
+ return null;
+ }
+ }
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index f5afb94..f16efbd 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -18,7 +18,6 @@ package android.widget;
import android.content.Context;
import android.database.DataSetObserver;
-import android.os.Handler;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 46c7d33..936a97d 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1009,7 +1009,7 @@ public class GridView extends AbsListView {
childHeight = child.getMeasuredHeight();
if (mRecycler.shouldRecycleViewType(p.viewType)) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, -1);
}
}
@@ -1148,7 +1148,7 @@ public class GridView extends AbsListView {
if (dataChanged) {
for (int i = 0; i < childCount; i++) {
- recycleBin.addScrapView(getChildAt(i));
+ recycleBin.addScrapView(getChildAt(i), firstPosition+i);
}
} else {
recycleBin.fillActiveViews(childCount, firstPosition);
@@ -1215,11 +1215,11 @@ public class GridView extends AbsListView {
recycleBin.scrapActiveViews();
if (sel != null) {
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
mSelectedTop = sel.getTop();
} else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
View child = getChildAt(mMotionPosition - mFirstPosition);
- if (child != null) positionSelector(child);
+ if (child != null) positionSelector(mMotionPosition, child);
} else {
mSelectedTop = 0;
mSelectorRect.setEmpty();
@@ -1391,6 +1391,11 @@ public class GridView extends AbsListView {
if (mCachingStarted) {
child.setDrawingCacheEnabled(true);
}
+
+ if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
}
/**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b5e103f..e0119e9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -581,7 +581,7 @@ public class ListView extends AbsListView {
final boolean scroll = scrollYDelta != 0;
if (scroll) {
scrollListItemsBy(-scrollYDelta);
- positionSelector(child);
+ positionSelector(INVALID_POSITION, child);
mSelectedTop = child.getTop();
invalidate();
}
@@ -1086,7 +1086,7 @@ public class ListView extends AbsListView {
if (recycleOnMeasure() && mRecycler.shouldRecycleViewType(
((LayoutParams) child.getLayoutParams()).viewType)) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, -1);
}
}
@@ -1203,7 +1203,7 @@ public class ListView extends AbsListView {
// Recycle the view before we possibly return from the method
if (recyle && recycleBin.shouldRecycleViewType(
((LayoutParams) child.getLayoutParams()).viewType)) {
- recycleBin.addScrapView(child);
+ recycleBin.addScrapView(child, -1);
}
returnedHeight += child.getMeasuredHeight();
@@ -1507,7 +1507,7 @@ public class ListView extends AbsListView {
// already cached in mHeaderViews;
if (dataChanged) {
for (int i = 0; i < childCount; i++) {
- recycleBin.addScrapView(getChildAt(i));
+ recycleBin.addScrapView(getChildAt(i), firstPosition+i);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(getChildAt(i),
ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, index, i);
@@ -1610,19 +1610,19 @@ public class ListView extends AbsListView {
if (focused != null) {
focused.clearFocus();
}
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
} else {
sel.setSelected(false);
mSelectorRect.setEmpty();
}
} else {
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
}
mSelectedTop = sel.getTop();
} else {
if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
View child = getChildAt(mMotionPosition - mFirstPosition);
- if (child != null) positionSelector(child);
+ if (child != null) positionSelector(mMotionPosition, child);
} else {
mSelectedTop = 0;
mSelectorRect.setEmpty();
@@ -1703,7 +1703,7 @@ public class ListView extends AbsListView {
if (!mDataChanged) {
- // Try to use an exsiting view for this position
+ // Try to use an existing view for this position
child = mRecycler.getActiveView(position);
if (child != null) {
if (ViewDebug.TRACE_RECYCLER) {
@@ -1820,6 +1820,11 @@ public class ListView extends AbsListView {
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
+
+ if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
}
@Override
@@ -2288,6 +2293,7 @@ public class ListView extends AbsListView {
}
View selectedView = getSelectedView();
+ int selectedPos = mSelectedPosition;
int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
int amountToScroll = amountToScroll(direction, nextSelectedPosition);
@@ -2305,6 +2311,7 @@ public class ListView extends AbsListView {
setSelectedPositionInt(nextSelectedPosition);
setNextSelectedPositionInt(nextSelectedPosition);
selectedView = getSelectedView();
+ selectedPos = nextSelectedPosition;
if (mItemsCanFocus && focusResult == null) {
// there was no new view found to take focus, make sure we
// don't leave focus with the old selection
@@ -2345,7 +2352,7 @@ public class ListView extends AbsListView {
if (needToRedraw) {
if (selectedView != null) {
- positionSelector(selectedView);
+ positionSelector(selectedPos, selectedView);
mSelectedTop = selectedView.getTop();
}
if (!awakenScrollBars()) {
@@ -2841,7 +2848,7 @@ public class ListView extends AbsListView {
AbsListView.LayoutParams layoutParams = (LayoutParams) first.getLayoutParams();
if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
detachViewFromParent(first);
- recycleBin.addScrapView(first);
+ recycleBin.addScrapView(first, mFirstPosition);
} else {
removeViewInLayout(first);
}
@@ -2872,7 +2879,7 @@ public class ListView extends AbsListView {
AbsListView.LayoutParams layoutParams = (LayoutParams) last.getLayoutParams();
if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
detachViewFromParent(last);
- recycleBin.addScrapView(last);
+ recycleBin.addScrapView(last, mFirstPosition+lastIndex);
} else {
removeViewInLayout(last);
}