List of usage examples for android.view View getLeft
@ViewDebug.CapturedViewProperty public final int getLeft()
From source file:com.appunite.list.ListView.java
/** * Add a view as a child and make sure it is measured (if necessary) and * positioned properly.//from w w w. ja va 2s. c o m * * @param child The view to add * @param position The position of this child * @param y The y position relative to which this view will be positioned * @param flowDown If true, align top edge to y. If false, align bottom * edge to y. * @param childrenLeft Left edge where children should be positioned * @param selected Is this position selected? * @param recycled Has this view been pulled from the recycle bin? If so it * does not need to be remeasured. */ private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft, 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... // noinspection unchecked AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams(); if (p == null) { p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { attachViewToParent(child, flowDown ? -1 : 0, p); } else { p.forceAdd = false; if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { p.recycledHeaderFooter = true; } addViewInLayout(child, flowDown ? -1 : 0, p, true); } if (updateChildSelected) { 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)); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { Compat.setActivated(child, mCheckStates.get(position)); } } if (needToMeasure) { int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left + mListPadding.right, p.width); int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } else { cleanupLayoutState(child); } final int w = child.getMeasuredWidth(); final int h = child.getMeasuredHeight(); final int childTop = flowDown ? y : y - h; if (needToMeasure) { final int childRight = childrenLeft + w; final int childBottom = childTop + h; child.layout(childrenLeft, childTop, childRight, childBottom); } else { child.offsetLeftAndRight(childrenLeft - child.getLeft()); child.offsetTopAndBottom(childTop - child.getTop()); } if (mCachingStarted && !child.isDrawingCacheEnabled()) { child.setDrawingCacheEnabled(true); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && recycled && (((AbsListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition) != position) { Compat.jumpDrawablesToCurrentState(child); } }
From source file:com.appunite.list.HorizontalListView.java
/** * Add a view as a child and make sure it is measured (if necessary) and * positioned properly./* ww w.ja va 2s .c o m*/ * * @param child The view to add * @param position The position of this child * @param x The x position relative to which this view will be positioned * @param flowRight If true, align top edge to x. If false, align bottom * edge to x. * @param childTop Left edge where children should be positioned * @param selected Is this position selected? * @param recycled Has this view been pulled from the recycle bin? If so it * does not need to be remeasured. */ private void setupChild(View child, int position, int x, boolean flowRight, int childTop, 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... // noinspection unchecked LayoutParams p = (LayoutParams) child.getLayoutParams(); if (p == null) { p = (LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { attachViewToParent(child, flowRight ? -1 : 0, p); } else { p.forceAdd = false; if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { p.recycledHeaderFooter = true; } addViewInLayout(child, flowRight ? -1 : 0, p, true); } if (updateChildSelected) { 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)); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { Compat.setActivated(child, mCheckStates.get(position)); } } if (needToMeasure) { int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, mListPadding.top + mListPadding.bottom, p.height); int lpWidth = p.width; int childWidthSpec; if (lpWidth > 0) { childWidthSpec = MeasureSpec.makeMeasureSpec(lpWidth, MeasureSpec.EXACTLY); } else { childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } else { cleanupLayoutState(child); } final int w = child.getMeasuredWidth(); final int h = child.getMeasuredHeight(); final int childLeft = flowRight ? x : x - w; if (needToMeasure) { final int childBottom = childTop + h; final int childRight = childLeft + w; child.layout(childLeft, childTop, childRight, childBottom); } else { child.offsetTopAndBottom(childTop - child.getTop()); child.offsetLeftAndRight(childLeft - child.getLeft()); } if (mCachingStarted && !child.isDrawingCacheEnabled()) { child.setDrawingCacheEnabled(true); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && recycled && (((LayoutParams) child.getLayoutParams()).scrappedFromPosition) != position) { Compat.jumpDrawablesToCurrentState(child); } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private void rememberSyncState() { if (getChildCount() == 0) { return;// www . ja v a 2 s. c o m } mNeedSync = true; if (mSelectedPosition >= 0) { View child = getChildAt(mSelectedPosition - mFirstPosition); mSyncRowId = mNextSelectedRowId; mSyncPosition = mNextSelectedPosition; if (child != null) { mSpecificStart = (mIsVertical ? child.getTop() : child.getLeft()); } mSyncMode = SYNC_SELECTED_POSITION; } else { // Sync the based on the offset of the first view View child = getChildAt(0); ListAdapter adapter = getAdapter(); if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { mSyncRowId = adapter.getItemId(mFirstPosition); } else { mSyncRowId = NO_ID; } mSyncPosition = mFirstPosition; if (child != null) { mSpecificStart = (mIsVertical ? child.getTop() : child.getLeft()); } mSyncMode = SYNC_FIRST_POSITION; } }
From source file:com.awrtechnologies.valor.valorfireplace.hlistview.widget.HListView.java
/** * Add a view as a child and make sure it is measured (if necessary) and positioned properly. * * @param child//from w w w . jav a 2s .co m * The view to add * @param position * The position of this child * @param x * The x position relative to which this view will be positioned * @param flowDown * If true, align left edge to x. If false, align right edge to x. * @param childrenTop * Top edge where children should be positioned * @param selected * Is this position selected? * @param recycled * Has this view been pulled from the recycle bin? If so it does not need to be remeasured. */ @TargetApi(11) private void setupChild(View child, int position, int x, boolean flowDown, int childrenTop, 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... // noinspection unchecked AbsHListView.LayoutParams p = (AbsHListView.LayoutParams) child.getLayoutParams(); if (p == null) { p = (AbsHListView.LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { attachViewToParent(child, flowDown ? -1 : 0, p); } else { p.forceAdd = false; if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { p.recycledHeaderFooter = true; } addViewInLayout(child, flowDown ? -1 : 0, p, true); } if (updateChildSelected) { child.setSelected(isSelected); } if (updateChildPressed) { child.setPressed(isPressed); } if (mChoiceMode != ListView.CHOICE_MODE_NONE && mCheckStates != null) { if (child instanceof Checkable) { ((Checkable) child).setChecked(mCheckStates.get(position, false)); } else if (android.os.Build.VERSION.SDK_INT >= 11) { child.setActivated(mCheckStates.get(position, false)); } } if (needToMeasure) { int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, mListPadding.top + mListPadding.bottom, p.height); int lpWidth = p.width; int childWidthSpec; if (lpWidth > 0) { childWidthSpec = View.MeasureSpec.makeMeasureSpec(lpWidth, View.MeasureSpec.EXACTLY); } else { childWidthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } else { cleanupLayoutState(child); } final int w = child.getMeasuredWidth(); final int h = child.getMeasuredHeight(); final int childLeft = flowDown ? x : x - w; if (needToMeasure) { final int childBottom = childrenTop + h; final int childRight = childLeft + w; child.layout(childLeft, childrenTop, childRight, childBottom); } else { child.offsetLeftAndRight(childLeft - child.getLeft()); child.offsetTopAndBottom(childrenTop - child.getTop()); } if (mCachingStarted && !child.isDrawingCacheEnabled()) { child.setDrawingCacheEnabled(true); } if (android.os.Build.VERSION.SDK_INT >= 11) { if (recycled && (((AbsHListView.LayoutParams) child.getLayoutParams()).scrappedFromPosition) != position) { child.jumpDrawablesToCurrentState(); } } }
From source file:com.artifex.mupdf.view.ThumbnailViews.java
private void handleDragChange(int delta) { // Time to start stealing events! Once we've stolen them, don't // let anyone steal from us. final ViewParent parent = getParent(); if (parent != null) { parent.requestDisallowInterceptTouchEvent(true); }/*from w w w. j ava 2s . co m*/ final int motionIndex; if (mMotionPosition >= 0) { motionIndex = mMotionPosition - mFirstPosition; } else { // If we don't have a motion position that we can reliably track, // pick something in the middle to make a best guess at things // below. motionIndex = getChildCount() / 2; } int motionViewPrevStart = 0; View motionView = this.getChildAt(motionIndex); if (motionView != null) { motionViewPrevStart = (mIsVertical ? motionView.getTop() : motionView.getLeft()); } boolean atEdge = trackMotionScroll(delta); motionView = this.getChildAt(motionIndex); if (motionView != null) { final int motionViewRealStart = (mIsVertical ? motionView.getTop() : motionView.getLeft()); if (atEdge) { final int overscroll = -delta - (motionViewRealStart - motionViewPrevStart); updateOverScrollState(delta, overscroll); } } }
From source file:com.artifex.mupdf.view.ThumbnailViews.java
boolean trackMotionScroll(int incrementalDelta) { final int childCount = getChildCount(); if (childCount == 0) { return true; }//from w w w . j av a 2 s . c om final View first = getChildAt(0); final int firstStart = (mIsVertical ? first.getTop() : first.getLeft()); final View last = getChildAt(childCount - 1); final int lastEnd = (mIsVertical ? last.getBottom() : last.getRight()); final int paddingTop = getPaddingTop(); final int paddingBottom = getPaddingBottom(); final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int paddingStart = (mIsVertical ? paddingTop : paddingLeft); final int spaceBefore = paddingStart - firstStart; final int end = (mIsVertical ? getHeight() - paddingBottom : getWidth() - paddingRight); final int spaceAfter = lastEnd - end; final int size; if (mIsVertical) { size = getHeight() - paddingBottom - paddingTop; } else { size = getWidth() - paddingRight - paddingLeft; } if (incrementalDelta < 0) { incrementalDelta = Math.max(-(size - 1), incrementalDelta); } else { incrementalDelta = Math.min(size - 1, incrementalDelta); } final int firstPosition = mFirstPosition; final boolean cannotScrollDown = (firstPosition == 0 && firstStart >= paddingStart && incrementalDelta >= 0); final boolean cannotScrollUp = (firstPosition + childCount == mItemCount && lastEnd <= end && incrementalDelta <= 0); if (cannotScrollDown || cannotScrollUp) { return incrementalDelta != 0; } final boolean inTouchMode = isInTouchMode(); if (inTouchMode) { hideSelector(); } int start = 0; int count = 0; final boolean down = (incrementalDelta < 0); if (down) { int childrenStart = -incrementalDelta + paddingStart; for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final int childEnd = (mIsVertical ? child.getBottom() : child.getRight()); if (childEnd >= childrenStart) { break; } count++; mRecycler.addScrapView(child, firstPosition + i); } } else { int childrenEnd = end - incrementalDelta; for (int i = childCount - 1; i >= 0; i--) { final View child = getChildAt(i); final int childStart = (mIsVertical ? child.getTop() : child.getLeft()); if (childStart <= childrenEnd) { break; } start = i; count++; mRecycler.addScrapView(child, firstPosition + i); } } mBlockLayoutRequests = true; if (count > 0) { detachViewsFromParent(start, count); } // invalidate before moving the children to avoid unnecessary invalidate // calls to bubble up from the children all the way to the top if (!awakenScrollbarsInternal()) { invalidate(); } offsetChildren(incrementalDelta); if (down) { mFirstPosition += count; } final int absIncrementalDelta = Math.abs(incrementalDelta); if (spaceBefore < absIncrementalDelta || spaceAfter < absIncrementalDelta) { fillGap(down); } if (!inTouchMode && mSelectedPosition != INVALID_POSITION) { final int childIndex = mSelectedPosition - mFirstPosition; if (childIndex >= 0 && childIndex < getChildCount()) { 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; invokeOnItemScrollListener(); return false; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private View moveSelection(View oldSelected, View newSelected, int delta, int start, int end) { final int selectedPosition = mSelectedPosition; final int oldSelectedStart = (mIsVertical ? oldSelected.getTop() : oldSelected.getLeft()); final int oldSelectedEnd = (mIsVertical ? oldSelected.getBottom() : oldSelected.getRight()); View selected = null;//from w w w. ja v a2s . co m if (delta > 0) { /* * Case 1: Scrolling down. */ /* * Before After * | | | | * +-------+ +-------+ * | A | | A | * | 1 | => +-------+ * +-------+ | B | * | B | | 2 | * +-------+ +-------+ * | | | | * * Try to keep the top of the previously selected item where it was. * oldSelected = A * selected = B */ // Put oldSelected (A) where it belongs oldSelected = makeAndAddView(selectedPosition - 1, oldSelectedStart, true, false); final int itemMargin = mItemMargin; // Now put the new selection (B) below that selected = makeAndAddView(selectedPosition, oldSelectedEnd + itemMargin, true, true); final int selectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); final int selectedEnd = (mIsVertical ? selected.getBottom() : selected.getRight()); // Some of the newly selected item extends below the bottom of the list if (selectedEnd > end) { // Find space available above the selection into which we can scroll upwards final int spaceBefore = selectedStart - start; // Find space required to bring the bottom of the selected item fully into view final int spaceAfter = selectedEnd - end; // Don't scroll more than half the size of the list final int halfSpace = (end - start) / 2; int offset = Math.min(spaceBefore, spaceAfter); offset = Math.min(offset, halfSpace); if (mIsVertical) { oldSelected.offsetTopAndBottom(-offset); selected.offsetTopAndBottom(-offset); } else { oldSelected.offsetLeftAndRight(-offset); selected.offsetLeftAndRight(-offset); } } // Fill in views before and after fillBefore(mSelectedPosition - 2, selectedStart - itemMargin); adjustViewsStartOrEnd(); fillAfter(mSelectedPosition + 1, selectedEnd + itemMargin); } else if (delta < 0) { /* * Case 2: Scrolling up. */ /* * Before After * | | | | * +-------+ +-------+ * | A | | A | * +-------+ => | 1 | * | B | +-------+ * | 2 | | B | * +-------+ +-------+ * | | | | * * Try to keep the top of the item about to become selected where it was. * newSelected = A * olSelected = B */ if (newSelected != null) { // Try to position the top of newSel (A) where it was before it was selected final int newSelectedStart = (mIsVertical ? newSelected.getTop() : newSelected.getLeft()); selected = makeAndAddView(selectedPosition, newSelectedStart, true, true); } else { // If (A) was not on screen and so did not have a view, position // it above the oldSelected (B) selected = makeAndAddView(selectedPosition, oldSelectedStart, false, true); } final int selectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); final int selectedEnd = (mIsVertical ? selected.getBottom() : selected.getRight()); // Some of the newly selected item extends above the top of the list if (selectedStart < start) { // Find space required to bring the top of the selected item fully into view final int spaceBefore = start - selectedStart; // Find space available below the selection into which we can scroll downwards final int spaceAfter = end - selectedEnd; // Don't scroll more than half the height of the list final int halfSpace = (end - start) / 2; int offset = Math.min(spaceBefore, spaceAfter); offset = Math.min(offset, halfSpace); if (mIsVertical) { selected.offsetTopAndBottom(offset); } else { selected.offsetLeftAndRight(offset); } } // Fill in views above and below fillBeforeAndAfter(selected, selectedPosition); } else { /* * Case 3: Staying still */ selected = makeAndAddView(selectedPosition, oldSelectedStart, true, true); final int selectedStart = (mIsVertical ? selected.getTop() : selected.getLeft()); final int selectedEnd = (mIsVertical ? selected.getBottom() : selected.getRight()); // We're staying still... if (oldSelectedStart < start) { // ... but the top of the old selection was off screen. // (This can happen if the data changes size out from under us) int newEnd = selectedEnd; if (newEnd < start + 20) { // Not enough visible -- bring it onscreen if (mIsVertical) { selected.offsetTopAndBottom(start - selectedStart); } else { selected.offsetLeftAndRight(start - selectedStart); } } } // Fill in views above and below fillBeforeAndAfter(selected, selectedPosition); } return selected; }
From source file:com.artifex.mupdf.view.ThumbnailViews.java
private void rememberSyncState() { if (getChildCount() == 0) { return;/*from w ww .j a va 2 s. c om*/ } mNeedSync = true; if (mSelectedPosition >= 0) { View child = getChildAt(mSelectedPosition - mFirstPosition); mSyncRowId = mNextSelectedRowId; mSyncPosition = mNextSelectedPosition; if (child != null) { mSpecificStart = (mIsVertical ? child.getTop() : child.getLeft()); } mSyncMode = SYNC_SELECTED_POSITION; } else { // Sync the based on the offset of the first view View child = getChildAt(0); ListAdapter adapter = getAdapter(); if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { mSyncRowId = adapter.getItemId(mFirstPosition); } else { mSyncRowId = NO_ID; } mSyncPosition = mFirstPosition; if (child != null) { mSpecificStart = child.getTop(); } mSyncMode = SYNC_FIRST_POSITION; } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private View fillSpecific(int position, int offset) { final boolean tempIsSelected = (position == mSelectedPosition); View temp = makeAndAddView(position, offset, true, tempIsSelected); // Possibly changed again in fillBefore if we add rows above this one. mFirstPosition = position;/* w w w . j a v a 2s . c om*/ final int itemMargin = mItemMargin; final int offsetBefore; if (mIsVertical) { offsetBefore = temp.getTop() - itemMargin; } else { offsetBefore = temp.getLeft() - itemMargin; } final View before = fillBefore(position - 1, offsetBefore); // This will correct for the top of the first view not touching the top of the list adjustViewsStartOrEnd(); final int offsetAfter; if (mIsVertical) { offsetAfter = temp.getBottom() + itemMargin; } else { offsetAfter = temp.getRight() + itemMargin; } final View after = fillAfter(position + 1, offsetAfter); final int childCount = getChildCount(); if (childCount > 0) { correctTooHigh(childCount); } if (tempIsSelected) { return temp; } else if (before != null) { return before; } else { return after; } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
/** * Determine how much we need to scroll in order to get the next selected view * visible. The amount is capped at {@link #getMaxScrollAmount()}. * * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or * {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending on the * current view orientation.//from w ww. j a v a 2 s . c o m * @param nextSelectedPosition The position of the next selection, or * {@link #INVALID_POSITION} if there is no next selectable position * * @return The amount to scroll. Note: this is always positive! Direction * needs to be taken into account when actually scrolling. */ private int amountToScroll(int direction, int nextSelectedPosition) { forceValidFocusDirection(direction); final int numChildren = getChildCount(); if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) { final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight()); int indexToMakeVisible = numChildren - 1; if (nextSelectedPosition != INVALID_POSITION) { indexToMakeVisible = nextSelectedPosition - mFirstPosition; } final int positionToMakeVisible = mFirstPosition + indexToMakeVisible; final View viewToMakeVisible = getChildAt(indexToMakeVisible); int goalEnd = end; if (positionToMakeVisible < mItemCount - 1) { goalEnd -= getArrowScrollPreviewLength(); } final int viewToMakeVisibleStart = (mIsVertical ? viewToMakeVisible.getTop() : viewToMakeVisible.getLeft()); final int viewToMakeVisibleEnd = (mIsVertical ? viewToMakeVisible.getBottom() : viewToMakeVisible.getRight()); if (viewToMakeVisibleEnd <= goalEnd) { // Target item is fully visible return 0; } if (nextSelectedPosition != INVALID_POSITION && (goalEnd - viewToMakeVisibleStart) >= getMaxScrollAmount()) { // Item already has enough of it visible, changing selection is good enough return 0; } int amountToScroll = (viewToMakeVisibleEnd - goalEnd); if (mFirstPosition + numChildren == mItemCount) { final View lastChild = getChildAt(numChildren - 1); final int lastChildEnd = (mIsVertical ? lastChild.getBottom() : lastChild.getRight()); // Last is last in list -> Make sure we don't scroll past it final int max = lastChildEnd - end; amountToScroll = Math.min(amountToScroll, max); } return Math.min(amountToScroll, getMaxScrollAmount()); } else { final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); int indexToMakeVisible = 0; if (nextSelectedPosition != INVALID_POSITION) { indexToMakeVisible = nextSelectedPosition - mFirstPosition; } final int positionToMakeVisible = mFirstPosition + indexToMakeVisible; final View viewToMakeVisible = getChildAt(indexToMakeVisible); int goalStart = start; if (positionToMakeVisible > 0) { goalStart += getArrowScrollPreviewLength(); } final int viewToMakeVisibleStart = (mIsVertical ? viewToMakeVisible.getTop() : viewToMakeVisible.getLeft()); final int viewToMakeVisibleEnd = (mIsVertical ? viewToMakeVisible.getBottom() : viewToMakeVisible.getRight()); if (viewToMakeVisibleStart >= goalStart) { // Item is fully visible return 0; } if (nextSelectedPosition != INVALID_POSITION && (viewToMakeVisibleEnd - goalStart) >= getMaxScrollAmount()) { // Item already has enough of it visible, changing selection is good enough return 0; } int amountToScroll = (goalStart - viewToMakeVisibleStart); if (mFirstPosition == 0) { final View firstChild = getChildAt(0); final int firstChildStart = (mIsVertical ? firstChild.getTop() : firstChild.getLeft()); // First is first in list -> make sure we don't scroll past it final int max = start - firstChildStart; amountToScroll = Math.min(amountToScroll, max); } return Math.min(amountToScroll, getMaxScrollAmount()); } }