diff options
| -rw-r--r-- | api/current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 326 | ||||
| -rw-r--r-- | core/java/android/widget/GridView.java | 10 | ||||
| -rw-r--r-- | core/java/android/widget/ListView.java | 117 |
4 files changed, 48 insertions, 409 deletions
diff --git a/api/current.txt b/api/current.txt index cb6f2c3780b7..14952772778e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -31256,12 +31256,10 @@ package android.widget { method public int getCheckedItemPosition(); method public android.util.SparseBooleanArray getCheckedItemPositions(); method public int getChoiceMode(); - method public int getFirstPositionForRow(int); method public int getListPaddingBottom(); method public int getListPaddingLeft(); method public int getListPaddingRight(); method public int getListPaddingTop(); - method public int getRowForPosition(int); method public android.view.View getSelectedView(); method public android.graphics.drawable.Drawable getSelector(); method public java.lang.CharSequence getTextFilter(); @@ -31307,7 +31305,6 @@ package android.widget { method public void setRemoteViewsAdapter(android.content.Intent); method public void setScrollIndicators(android.view.View, android.view.View); method public void setScrollingCacheEnabled(boolean); - method public void setSelectionFromTop(int, int); method public void setSelector(int); method public void setSelector(android.graphics.drawable.Drawable); method public void setSmoothScrollbarEnabled(boolean); @@ -32408,6 +32405,7 @@ package android.widget { method public void setOverscrollHeader(android.graphics.drawable.Drawable); method public void setSelection(int); method public void setSelectionAfterHeaderView(); + method public void setSelectionFromTop(int, int); method public void smoothScrollByOffset(int); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 16fab1f42a74..90866d60ffae 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -36,7 +36,6 @@ import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.util.LongSparseArray; -import android.util.MathUtils; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.StateSet; @@ -61,8 +60,6 @@ import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.inputmethod.BaseInputConnection; @@ -421,7 +418,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Handles scrolling between positions within the list. */ - SubPositionScroller mPositionScroller; + PositionScroller mPositionScroller; /** * The offset in pixels form the top of the AdapterView to the top @@ -4842,14 +4839,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void smoothScrollToPosition(int position) { if (mPositionScroller == null) { - mPositionScroller = new SubPositionScroller(); + mPositionScroller = new PositionScroller(); } mPositionScroller.start(position); } /** * Smoothly scroll to the specified adapter position. The view will scroll - * such that the indicated position is displayed <code>offset</code> pixels below + * such that the indicated position is displayed <code>offset</code> pixels from * the top edge of the view. If this is impossible, (e.g. the offset would scroll * the first or last item beyond the boundaries of the list) it will get as close * as possible. The scroll will take <code>duration</code> milliseconds to complete. @@ -4861,14 +4858,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void smoothScrollToPositionFromTop(int position, int offset, int duration) { if (mPositionScroller == null) { - mPositionScroller = new SubPositionScroller(); + mPositionScroller = new PositionScroller(); } mPositionScroller.startWithOffset(position, offset, duration); } /** * Smoothly scroll to the specified adapter position. The view will scroll - * such that the indicated position is displayed <code>offset</code> pixels below + * such that the indicated position is displayed <code>offset</code> pixels from * the top edge of the view. If this is impossible, (e.g. the offset would scroll * the first or last item beyond the boundaries of the list) it will get as close * as possible. @@ -4879,9 +4876,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void smoothScrollToPositionFromTop(int position, int offset) { if (mPositionScroller == null) { - mPositionScroller = new SubPositionScroller(); + mPositionScroller = new PositionScroller(); } - mPositionScroller.startWithOffset(position, offset, offset); + mPositionScroller.startWithOffset(position, offset); } /** @@ -4895,7 +4892,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void smoothScrollToPosition(int position, int boundPosition) { if (mPositionScroller == null) { - mPositionScroller = new SubPositionScroller(); + mPositionScroller = new PositionScroller(); } mPositionScroller.start(position, boundPosition); } @@ -6994,311 +6991,4 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return null; } } - - /** - * Returns the height of a row, which is computed as the maximum height of - * the items in the row. - * - * @param row the row index - * @return row height in pixels - */ - private int getHeightForRow(int row) { - final int firstRowPosition = getFirstPositionForRow(row); - final int lastRowPosition = getFirstPositionForRow(row + 1); - int maxHeight = 0; - for (int i = firstRowPosition; i < lastRowPosition; i++) { - final int height = getHeightForPosition(i); - if (height > maxHeight) { - maxHeight = height; - } - } - return maxHeight; - } - - /** - * Returns the height of the view for the specified position. - * - * @param position the item position - * @return view height in pixels - */ - int getHeightForPosition(int position) { - final int firstVisiblePosition = getFirstVisiblePosition(); - final int childCount = getChildCount(); - final int index = position - firstVisiblePosition; - if (position >= 0 && position < childCount) { - final View view = getChildAt(index); - return view.getHeight(); - } else { - final View view = obtainView(position, mIsScrap); - view.measure(mWidthMeasureSpec, MeasureSpec.UNSPECIFIED); - final int height = view.getMeasuredHeight(); - mRecycler.addScrapView(view, position); - return height; - } - } - - /** - * Returns the row for the specified item position. - * - * @param position the item position - * @return the row index - */ - public int getRowForPosition(int position) { - return position; - } - - /** - * Returns the first item position within the specified row. - * - * @param row the row - * @return the item position - */ - public int getFirstPositionForRow(int row) { - return row; - } - - /** - * Sets the selected item and positions the selection y pixels from the top edge - * of the ListView. (If in touch mode, the item will not be selected but it will - * still be positioned appropriately.) - * - * @param position Index (starting at 0) of the data item to be selected. - * @param y The distance from the top edge of the ListView (plus padding) that the - * item will be positioned. - */ - public void setSelectionFromTop(int position, int y) { - if (mAdapter == null) { - return; - } - - if (!isInTouchMode()) { - position = lookForSelectablePosition(position, true); - if (position >= 0) { - setNextSelectedPositionInt(position); - } - } else { - mResurrectToPosition = position; - } - - if (position >= 0) { - mLayoutMode = LAYOUT_SPECIFIC; - mSpecificTop = mListPadding.top + y; - - if (mNeedSync) { - mSyncPosition = position; - mSyncRowId = mAdapter.getItemId(position); - } - - if (mPositionScroller != null) { - mPositionScroller.stop(); - } - requestLayout(); - } - } - - class SubPositionScroller { - private static final int DEFAULT_SCROLL_DURATION = 200; - - private SubScroller mSubScroller; - private int mOffset; - - /** - * Scroll the minimum amount to get the target view entirely on-screen. - */ - private void scrollToPosition(final int targetPosition, final boolean useOffset, - final int offset, final int boundPosition, final int duration) { - stop(); - - if (mDataChanged) { - // Wait until we're back in a stable state to try this. - mPositionScrollAfterLayout = new Runnable() { - @Override - public void run() { - scrollToPosition( - targetPosition, useOffset, offset, boundPosition, duration); - } - }; - return; - } - - final int firstPosition = getFirstVisiblePosition(); - final int lastPosition = firstPosition + getChildCount(); - final int targetRow = getRowForPosition(targetPosition); - final int firstRow = getRowForPosition(firstPosition); - final int lastRow = getRowForPosition(lastPosition); - if (useOffset || targetRow <= firstRow) { - mOffset = offset; - } else if (targetRow >= lastRow - 1) { - final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom(); - mOffset = listHeight - getHeightForPosition(targetPosition); - } else { - // Don't scroll, target is entirely on-screen. - return; - } - - float endSubRow = targetRow; - if (boundPosition != INVALID_POSITION) { - final int boundRow = getRowForPosition(boundPosition); - if (boundRow >= firstRow && boundRow < lastRow) { - endSubRow = computeBoundSubRow(targetRow, boundRow); - } - } - - final View firstChild = getChildAt(0); - final float startOffsetRatio = -firstChild.getTop() / (float) firstChild.getHeight(); - final float startSubRow = firstRow + startOffsetRatio; - if (startSubRow == endSubRow && mOffset == 0) { - // Don't scroll, target is already in position. - return; - } - - if (mSubScroller == null) { - mSubScroller = new SubScroller(); - } - mSubScroller.startScroll(startSubRow, endSubRow, duration); - - postOnAnimation(mAnimationFrame); - } - - private float computeBoundSubRow(int targetRow, int boundRow) { - // Compute the target and offset as a sub-position. - int remainingOffset = mOffset; - int targetHeight = getHeightForRow(targetRow - 1); - while (remainingOffset > 0) { - remainingOffset -= targetHeight; - targetRow--; - targetHeight = getHeightForRow(targetRow - 1); - } - final float targetSubRow = targetRow - remainingOffset / targetHeight; - mOffset = 0; - - if (targetSubRow >= boundRow) { - // End position would push the bound position above the list. - return boundRow; - } - - // Compute the closest possible sub-position that wouldn't push the - // bound position's view further below the list. - final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom(); - final int boundHeight = getHeightForRow(boundRow); - int endRow = boundRow; - int totalHeight = boundHeight; - int endHeight; - do { - endRow--; - endHeight = getHeightForRow(endRow); - totalHeight += endHeight; - } while (totalHeight < listHeight && endRow > 0); - - final float endOffsetRatio = (totalHeight - listHeight) / (float) endHeight; - final float boundSubRow = endRow + endOffsetRatio; - return Math.max(boundSubRow, targetSubRow); - } - - /** - * @param position - * @param boundPosition - */ - public void start(int position, int boundPosition) { - scrollToPosition(position, false, 0, boundPosition, DEFAULT_SCROLL_DURATION); - } - - /** - * @param position - * @param offset - * @param duration - */ - public void startWithOffset(int position, int offset, int duration) { - scrollToPosition(position, true, offset, INVALID_POSITION, duration); - } - - /** - * @param position - */ - public void start(int position) { - scrollToPosition(position, false, 0, INVALID_POSITION, DEFAULT_SCROLL_DURATION); - } - - public void stop() { - removeCallbacks(mAnimationFrame); - } - - private void onAnimationFrame() { - final boolean shouldPost = mSubScroller.computePosition(); - final float subRow = mSubScroller.getPosition(); - - final int row = (int) subRow; - final int position = getFirstPositionForRow(row); - final int rowHeight = getHeightForRow(row); - final int offset = (int) (rowHeight * (subRow - row)); - final int addOffset = (int) (mOffset * mSubScroller.getInterpolatedValue()); - setSelectionFromTop(position, -offset + addOffset); - - if (shouldPost) { - postOnAnimation(mAnimationFrame); - } - } - - private Runnable mAnimationFrame = new Runnable() { - @Override - public void run() { - onAnimationFrame(); - } - }; - } - - /** - * Scroller capable of returning floating point positions. - */ - private static class SubScroller { - private final Interpolator mInterpolator; - - private float mStartPosition; - private float mEndPosition; - private long mStartTime; - private long mDuration; - - private float mPosition; - private float mInterpolatedValue; - - public SubScroller() { - this(null); - } - - public SubScroller(Interpolator interpolator) { - if (interpolator == null) { - mInterpolator = new AccelerateDecelerateInterpolator(); - } else { - mInterpolator = interpolator; - } - } - - public void startScroll(float startPosition, float endPosition, int duration) { - mStartPosition = startPosition; - mEndPosition = endPosition; - mDuration = duration; - - mStartTime = AnimationUtils.currentAnimationTimeMillis(); - mPosition = startPosition; - mInterpolatedValue = 0; - } - - public boolean computePosition() { - final long elapsed = AnimationUtils.currentAnimationTimeMillis() - mStartTime; - final float value = MathUtils.constrain(elapsed / (float) mDuration, 0, 1); - - mInterpolatedValue = mInterpolator.getInterpolation(value); - mPosition = (mEndPosition - mStartPosition) * mInterpolatedValue + mStartPosition; - - return elapsed < mDuration; - } - - public float getPosition() { - return mPosition; - } - - public float getInterpolatedValue() { - return mInterpolatedValue; - } - } } diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index 0b424f72be21..acd711d61e8c 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -1027,16 +1027,6 @@ public class GridView extends AbsListView { } @Override - public int getRowForPosition(int position) { - return position / mNumColumns; - } - - @Override - public int getFirstPositionForRow(int row) { - return row * mNumColumns; - } - - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Sets up mListPadding super.onMeasure(widthMeasureSpec, heightMeasureSpec); diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index f937cd629d90..c4617236d041 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1892,6 +1892,45 @@ public class ListView extends AbsListView { } /** + * Sets the selected item and positions the selection y pixels from the top edge + * of the ListView. (If in touch mode, the item will not be selected but it will + * still be positioned appropriately.) + * + * @param position Index (starting at 0) of the data item to be selected. + * @param y The distance from the top edge of the ListView (plus padding) that the + * item will be positioned. + */ + public void setSelectionFromTop(int position, int y) { + if (mAdapter == null) { + return; + } + + if (!isInTouchMode()) { + position = lookForSelectablePosition(position, true); + if (position >= 0) { + setNextSelectedPositionInt(position); + } + } else { + mResurrectToPosition = position; + } + + if (position >= 0) { + mLayoutMode = LAYOUT_SPECIFIC; + mSpecificTop = mListPadding.top + y; + + if (mNeedSync) { + mSyncPosition = position; + mSyncRowId = mAdapter.getItemId(position); + } + + if (mPositionScroller != null) { + mPositionScroller.stop(); + } + requestLayout(); + } + } + + /** * Makes the item at the supplied position selected. * * @param position the position of the item to select @@ -3707,84 +3746,6 @@ public class ListView extends AbsListView { } @Override - int getHeightForPosition(int position) { - final int height = super.getHeightForPosition(position); - if (shouldAdjustHeightForDivider(position)) { - return height + mDividerHeight; - } - return height; - } - - private boolean shouldAdjustHeightForDivider(int itemIndex) { - final int dividerHeight = mDividerHeight; - final Drawable overscrollHeader = mOverScrollHeader; - final Drawable overscrollFooter = mOverScrollFooter; - final boolean drawOverscrollHeader = overscrollHeader != null; - final boolean drawOverscrollFooter = overscrollFooter != null; - final boolean drawDividers = dividerHeight > 0 && mDivider != null; - - if (drawDividers) { - final boolean fillForMissingDividers = isOpaque() && !super.isOpaque(); - final int itemCount = mItemCount; - final int headerCount = mHeaderViewInfos.size(); - final int footerLimit = (itemCount - mFooterViewInfos.size()); - final boolean isHeader = (itemIndex < headerCount); - final boolean isFooter = (itemIndex >= footerLimit); - final boolean headerDividers = mHeaderDividersEnabled; - final boolean footerDividers = mFooterDividersEnabled; - if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) { - final ListAdapter adapter = mAdapter; - if (!mStackFromBottom) { - final boolean isLastItem = (itemIndex == (itemCount - 1)); - if (!drawOverscrollFooter || !isLastItem) { - final int nextIndex = itemIndex + 1; - // Draw dividers between enabled items, headers - // and/or footers when enabled and requested, and - // after the last enabled item. - if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader - && (nextIndex >= headerCount)) && (isLastItem - || adapter.isEnabled(nextIndex) && (footerDividers || !isFooter - && (nextIndex < footerLimit)))) { - return true; - } else if (fillForMissingDividers) { - return true; - } - } - } else { - final int start = drawOverscrollHeader ? 1 : 0; - final boolean isFirstItem = (itemIndex == start); - if (!isFirstItem) { - final int previousIndex = (itemIndex - 1); - // Draw dividers between enabled items, headers - // and/or footers when enabled and requested, and - // before the first enabled item. - if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader - && (previousIndex >= headerCount)) && (isFirstItem || - adapter.isEnabled(previousIndex) && (footerDividers || !isFooter - && (previousIndex < footerLimit)))) { - return true; - } else if (fillForMissingDividers) { - return true; - } - } - } - } - } - - return false; - } - - @Override - public int getRowForPosition(int position) { - return position; - } - - @Override - public int getFirstPositionForRow(int row) { - return row; - } - - @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(ListView.class.getName()); |