List of usage examples for android.view View offsetTopAndBottom
public void offsetTopAndBottom(int offset)
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 ww w. j a v a 2 s . co 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.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 ww . j a va 2s.com*/ * 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.boutline.sports.helpers.TwoWayView.java
private View fillFromSelection(int selectedTop, int start, int end) { final int selectedPosition = mSelectedPosition; View selected = makeAndAddView(selectedPosition, selectedTop, true, true); final int selectedStart = getChildStartEdge(selected); final int selectedEnd = getChildEndEdge(selected); // 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 spaceAbove = selectedStart - start; // Find space required to bring the bottom of the selected item // fully into view final int spaceBelow = selectedEnd - end; final int offset = Math.min(spaceAbove, spaceBelow); // Now offset the selected item to get it into view selected.offsetTopAndBottom(-offset); } else if (selectedStart < start) { // Find space required to bring the top of the selected item fully // into view final int spaceAbove = start - selectedStart; // Find space available below the selection into which we can scroll // downwards final int spaceBelow = end - selectedEnd; final int offset = Math.min(spaceAbove, spaceBelow); // Offset the selected item to get it into view selected.offsetTopAndBottom(offset); }//from w w w . j a v a2s . c o m // Fill in views above and below fillBeforeAndAfter(selected, selectedPosition); correctTooHigh(getChildCount()); return selected; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private View fillFromSelection(int selectedTop, int start, int end) { final int selectedPosition = mSelectedPosition; View selected; selected = makeAndAddView(selectedPosition, selectedTop, 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 spaceAbove = selectedStart - start; // Find space required to bring the bottom of the selected item // fully into view final int spaceBelow = selectedEnd - end; final int offset = Math.min(spaceAbove, spaceBelow); // Now offset the selected item to get it into view selected.offsetTopAndBottom(-offset); } else if (selectedStart < start) { // Find space required to bring the top of the selected item fully // into view final int spaceAbove = start - selectedStart; // Find space available below the selection into which we can scroll // downwards final int spaceBelow = end - selectedEnd; final int offset = Math.min(spaceAbove, spaceBelow); // Offset the selected item to get it into view selected.offsetTopAndBottom(offset); }/*from ww w.ja v a 2 s . co m*/ // Fill in views above and below fillBeforeAndAfter(selected, selectedPosition); correctTooHigh(getChildCount()); return selected; }
From source file:com.artifex.mupdflib.TwoWayView.java
private View fillFromSelection(int selectedTop, int start, int end) { int fadingEdgeLength = getFadingEdgeLength(); final int selectedPosition = mSelectedPosition; final int minStart = getMinSelectionPixel(start, fadingEdgeLength, selectedPosition); final int maxEnd = getMaxSelectionPixel(end, fadingEdgeLength, selectedPosition); View selected = makeAndAddView(selectedPosition, selectedTop, true, true); final int selectedStart = getChildStartEdge(selected); final int selectedEnd = getChildEndEdge(selected); // Some of the newly selected item extends below the bottom of the list if (selectedEnd > maxEnd) { // Find space available above the selection into which we can scroll // upwards final int spaceAbove = selectedStart - minStart; // Find space required to bring the bottom of the selected item // fully into view final int spaceBelow = selectedEnd - maxEnd; final int offset = Math.min(spaceAbove, spaceBelow); // Now offset the selected item to get it into view selected.offsetTopAndBottom(-offset); } else if (selectedStart < minStart) { // Find space required to bring the top of the selected item fully // into view final int spaceAbove = minStart - selectedStart; // Find space available below the selection into which we can scroll // downwards final int spaceBelow = maxEnd - selectedEnd; final int offset = Math.min(spaceAbove, spaceBelow); // Offset the selected item to get it into view selected.offsetTopAndBottom(offset); }/*from w w w . j a v a 2 s .c om*/ // Fill in views above and below fillBeforeAndAfter(selected, selectedPosition); correctTooHigh(getChildCount()); return selected; }
From source file:com.boutline.sports.helpers.TwoWayView.java
private View moveSelection(View oldSelected, View newSelected, int delta, int start, int end) { final int selectedPosition = mSelectedPosition; final int oldSelectedStart = getChildStartEdge(oldSelected); final int oldSelectedEnd = getChildEndEdge(oldSelected); View selected = null;//from ww w. j av a2 s .c o 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 = getChildStartEdge(selected); final int selectedEnd = getChildEndEdge(selected); // 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 = getChildStartEdge(selected); final int selectedEnd = getChildEndEdge(selected); // 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 = getChildStartEdge(selected); final int selectedEnd = getChildEndEdge(selected); // 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 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. j av a2s .c om 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:org.lucasr.twowayview.TwoWayView.java
@TargetApi(11) private void setupChild(View child, int position, int top, int left, boolean flow, boolean selected, boolean recycled) { final boolean isSelected = selected && shouldShowSelector(); final boolean updateChildSelected = isSelected != child.isSelected(); final int touchMode = mTouchMode; final boolean isPressed = touchMode > TOUCH_MODE_DOWN && touchMode < TOUCH_MODE_DRAGGING && 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... LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); }/*from w w w.java 2 s. c o m*/ lp.viewType = mAdapter.getItemViewType(position); if (recycled && !lp.forceAdd) { attachViewToParent(child, (flow ? -1 : 0), lp); } else { lp.forceAdd = false; addViewInLayout(child, (flow ? -1 : 0), lp, true); } if (updateChildSelected) { child.setSelected(isSelected); } if (updateChildPressed) { child.setPressed(isPressed); } if (mChoiceMode.compareTo(ChoiceMode.NONE) != 0 && mCheckStates != null) { if (child instanceof Checkable) { ((Checkable) child).setChecked(mCheckStates.get(position)); } else if (Build.VERSION.SDK_INT >= HONEYCOMB) { child.setActivated(mCheckStates.get(position)); } } if (needToMeasure) { measureChild(child, lp); } else { cleanupLayoutState(child); } final int w = child.getMeasuredWidth(); final int h = child.getMeasuredHeight(); final int childTop = (mIsVertical && !flow ? top - h : top); final int childLeft = (!mIsVertical && !flow ? left - w : left); if (needToMeasure) { final int childRight = childLeft + w; final int childBottom = childTop + h; child.layout(childLeft, childTop, childRight, childBottom); } else { child.offsetLeftAndRight(childLeft - child.getLeft()); child.offsetTopAndBottom(childTop - child.getTop()); } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
@TargetApi(11) private void setupChild(View child, int position, int top, int left, boolean flow, boolean selected, boolean recycled) { final boolean isSelected = selected && shouldShowSelector(); final boolean updateChildSelected = isSelected != child.isSelected(); final int touchMode = mTouchMode; final boolean isPressed = touchMode > TOUCH_MODE_DOWN && touchMode < TOUCH_MODE_DRAGGING && 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... LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); }/*from w w w . ja v a 2s .c om*/ lp.viewType = mAdapter.getItemViewType(position); if (recycled && !lp.forceAdd) { attachViewToParent(child, (flow ? -1 : 0), lp); } else { lp.forceAdd = false; addViewInLayout(child, (flow ? -1 : 0), lp, true); } if (updateChildSelected) { child.setSelected(isSelected); } if (updateChildPressed) { child.setPressed(isPressed); } if (mChoiceMode.compareTo(ChoiceMode.NONE) != 0 && mCheckStates != null) { if (child instanceof Checkable) { ((Checkable) child).setChecked(mCheckStates.get(position)); } else if (getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { child.setActivated(mCheckStates.get(position)); } } if (needToMeasure) { measureChild(child, lp); } else { cleanupLayoutState(child); } final int w = child.getMeasuredWidth(); final int h = child.getMeasuredHeight(); final int childTop = (mIsVertical && !flow ? top - h : top); final int childLeft = (!mIsVertical && !flow ? left - w : left); if (needToMeasure) { final int childRight = childLeft + w; final int childBottom = childTop + h; child.layout(childLeft, childTop, childRight, childBottom); } else { child.offsetLeftAndRight(childLeft - child.getLeft()); child.offsetTopAndBottom(childTop - child.getTop()); } }
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 www .j a va 2 s .c o 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; }