List of usage examples for android.view View getRight
@ViewDebug.CapturedViewProperty public final int getRight()
From source file:com.freeman.support.v7.widget.RecyclerView.java
/** * Wrapper around layoutChildren() that handles animating changes caused by layout. * Animations work on the assumption that there are five different kinds of items * in play://from w w w. ja va 2s . co m * PERSISTENT: items are visible before and after layout * REMOVED: items were visible before layout and were removed by the app * ADDED: items did not exist before layout and were added by the app * DISAPPEARING: items exist in the data set before/after, but changed from * visible to non-visible in the process of layout (they were moved off * screen as a side-effect of other changes) * APPEARING: items exist in the data set before/after, but changed from * non-visible to visible in the process of layout (they were moved on * screen as a side-effect of other changes) * The overall approach figures out what items exist before/after layout and * infers one of the five above states for each of the items. Then the animations * are set up accordingly: * PERSISTENT views are moved ({@link com.freeman.support.v7.widget.RecyclerView.ItemAnimator#animateMove(com.freeman.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int)}) * REMOVED views are removed ({@link com.freeman.support.v7.widget.RecyclerView.ItemAnimator#animateRemove(com.freeman.support.v7.widget.RecyclerView.ViewHolder)}) * ADDED views are added ({@link com.freeman.support.v7.widget.RecyclerView.ItemAnimator#animateAdd(com.freeman.support.v7.widget.RecyclerView.ViewHolder)}) * DISAPPEARING views are moved off screen * APPEARING views are moved on screen */ void dispatchLayout() { if (mAdapter == null) { Log.e(TAG, "No adapter attached; skipping layout"); return; } eatRequestLayout(); // simple animations are a subset of advanced animations (which will cause a // prelayout step) boolean animateChangesSimple = mItemAnimator != null && mItemsAddedOrRemoved && !mItemsChanged; final boolean animateChangesAdvanced = mIsPredictiveAnimationsEnabled && animateChangesSimple && predictiveItemAnimationsEnabled(); mItemsAddedOrRemoved = mItemsChanged = false; ArrayMap<View, Rect> appearingViewInitialBounds = null; mState.mInPreLayout = animateChangesAdvanced; mState.mItemCount = mAdapter.getItemCount(); if (animateChangesSimple) { // Step 0: Find out where all non-removed items are, pre-layout mState.mPreLayoutHolderMap.clear(); mState.mPostLayoutHolderMap.clear(); int count = getChildCount(); for (int i = 0; i < count; ++i) { final ViewHolder holder = getChildViewHolderInt(getChildAt(i)); final View view = holder.itemView; mState.mPreLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), holder.mPosition)); } } if (animateChangesAdvanced) { // Step 1: run prelayout: This will use the old positions of items. The layout manager // is expected to layout everything, even removed items (though not to add removed // items back to the container). This gives the pre-layout position of APPEARING views // which come into existence as part of the real layout. mInPreLayout = true; final boolean didStructureChange = mState.mStructureChanged; mState.mStructureChanged = false; // temporarily disable flag because we are asking for previous layout mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = didStructureChange; mInPreLayout = false; appearingViewInitialBounds = new ArrayMap<View, Rect>(); for (int i = 0; i < getChildCount(); ++i) { boolean found = false; View child = getChildAt(i); for (int j = 0; j < mState.mPreLayoutHolderMap.size(); ++j) { ViewHolder holder = mState.mPreLayoutHolderMap.keyAt(j); if (holder.itemView == child) { found = true; continue; } } if (!found) { appearingViewInitialBounds.put(child, new Rect(child.getLeft(), child.getTop(), child.getRight(), child.getBottom())); } } } clearOldPositions(); dispatchLayoutUpdates(); mState.mItemCount = mAdapter.getItemCount(); // Step 2: Run layout mState.mInPreLayout = false; mLayout.onLayoutChildren(mRecycler, mState); mState.mStructureChanged = false; mPendingSavedState = null; // onLayoutChildren may have caused client code to disable item animations; re-check animateChangesSimple = animateChangesSimple && mItemAnimator != null; if (animateChangesSimple) { // Step 3: Find out where things are now, post-layout int count = getChildCount(); for (int i = 0; i < count; ++i) { ViewHolder holder = getChildViewHolderInt(getChildAt(i)); final View view = holder.itemView; mState.mPostLayoutHolderMap.put(holder, new ItemHolderInfo(holder, view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), holder.mPosition)); } // Step 4: Animate DISAPPEARING and REMOVED items int preLayoutCount = mState.mPreLayoutHolderMap.size(); for (int i = preLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPreLayoutHolderMap.keyAt(i); if (!mState.mPostLayoutHolderMap.containsKey(itemHolder)) { ItemHolderInfo disappearingItem = mState.mPreLayoutHolderMap.valueAt(i); mState.mPreLayoutHolderMap.removeAt(i); View disappearingItemView = disappearingItem.holder.itemView; removeDetachedView(disappearingItemView, false); mRecycler.unscrapView(disappearingItem.holder); animateDisappearance(disappearingItem); } } // Step 5: Animate APPEARING and ADDED items int postLayoutCount = mState.mPostLayoutHolderMap.size(); if (postLayoutCount > 0) { for (int i = postLayoutCount - 1; i >= 0; i--) { ViewHolder itemHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo info = mState.mPostLayoutHolderMap.valueAt(i); if ((mState.mPreLayoutHolderMap.isEmpty() || !mState.mPreLayoutHolderMap.containsKey(itemHolder))) { mState.mPostLayoutHolderMap.removeAt(i); Rect initialBounds = (appearingViewInitialBounds != null) ? appearingViewInitialBounds.get(itemHolder.itemView) : null; animateAppearance(itemHolder, initialBounds, info.left, info.top); } } } // Step 6: Animate PERSISTENT items count = mState.mPostLayoutHolderMap.size(); for (int i = 0; i < count; ++i) { ViewHolder postHolder = mState.mPostLayoutHolderMap.keyAt(i); ItemHolderInfo postInfo = mState.mPostLayoutHolderMap.valueAt(i); ItemHolderInfo preInfo = mState.mPreLayoutHolderMap.get(postHolder); if (preInfo != null && postInfo != null) { if (preInfo.left != postInfo.left || preInfo.top != postInfo.top) { postHolder.setIsRecyclable(false); if (mIsDebugLoggingEnabled) { Log.d(TAG, "PERSISTENT: " + postHolder + " with view " + postHolder.itemView); } if (mItemAnimator.animateMove(postHolder, preInfo.left, preInfo.top, postInfo.left, postInfo.top)) { postAnimationRunner(); } } } } } resumeRequestLayout(false); mLayout.removeAndRecycleScrapInt(mRecycler, !animateChangesAdvanced); mState.mPreviousLayoutItemCount = mState.mItemCount; mState.mDeletedInvisibleItemCountSincePreviousLayout = 0; }
From source file:com.appunite.list.AbsHorizontalListView.java
/** * Track a motion scroll/*from w w w .jav a2s. co m*/ * * @param deltaX Amount to offset mMotionView. This is the accumulated delta since the motion * began. Positive numbers mean the user's finger is moving down the screen. * @param incrementalDeltaX Change in deltaX from the previous event. * @return true if we're already at the beginning/end of the list and have nothing to do. */ boolean trackMotionScroll(int deltaX, int incrementalDeltaX) { final int childCount = getChildCount(); if (childCount == 0) { return true; } final int firstLeft = getChildAt(0).getLeft(); final int lastRight = getChildAt(childCount - 1).getRight(); final Rect listPadding = mListPadding; // "effective padding" In this case is the amount of padding that affects // how much space should not be filled by items. If we don't clip to padding // there is no effective padding. int effectivePaddingLeft = 0; int effectivePaddingRight = 0; if (mClipToPadding) { effectivePaddingLeft = listPadding.left; effectivePaddingRight = listPadding.right; } // FIXME account for grid vertical spacing too? final int spaceToLeft = effectivePaddingLeft - firstLeft; final int end = getWidth() - effectivePaddingRight; final int spaceToRight = lastRight - end; final int width = getWidth() - getPaddingRight() - getPaddingLeft(); if (deltaX < 0) { deltaX = Math.max(-(width - 1), deltaX); } else { deltaX = Math.min(width - 1, deltaX); } if (incrementalDeltaX < 0) { incrementalDeltaX = Math.max(-(width - 1), incrementalDeltaX); } else { incrementalDeltaX = Math.min(width - 1, incrementalDeltaX); } final int firstPosition = mFirstPosition; // Update our guesses for where the first and last views are if (firstPosition == 0) { mFirstPositionDistanceGuess = firstLeft - listPadding.top; } else { mFirstPositionDistanceGuess += incrementalDeltaX; } if (firstPosition + childCount == mItemCount) { mLastPositionDistanceGuess = lastRight + listPadding.bottom; } else { mLastPositionDistanceGuess += incrementalDeltaX; } final boolean cannotScrollRight = (firstPosition == 0 && firstLeft >= listPadding.left && incrementalDeltaX >= 0); final boolean cannotScrollLeft = (firstPosition + childCount == mItemCount && lastRight <= getWidth() - listPadding.right && incrementalDeltaX <= 0); if (cannotScrollRight || cannotScrollLeft) { return incrementalDeltaX != 0; } final boolean toRight = incrementalDeltaX < 0; final boolean inTouchMode = isInTouchMode(); if (inTouchMode) { hideSelector(); } final int headerViewsCount = getHeaderViewsCount(); final int footerViewsStart = mItemCount - getFooterViewsCount(); int start = 0; int count = 0; if (toRight) { int left = -incrementalDeltaX; if (mClipToPadding) { left += listPadding.left; } for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getRight() >= left) { break; } else { count++; int position = firstPosition + i; if (position >= headerViewsCount && position < footerViewsStart) { mRecycler.addScrapView(child, position); } } } } else { int right = getWidth() - incrementalDeltaX; if (mClipToPadding) { right -= listPadding.right; } for (int i = childCount - 1; i >= 0; i--) { final View child = getChildAt(i); if (child.getLeft() <= right) { break; } else { start = i; count++; int position = firstPosition + i; if (position >= headerViewsCount && position < footerViewsStart) { mRecycler.addScrapView(child, position); } } } } mMotionViewNewLeft = mMotionViewOriginalLeft + deltaX; mBlockLayoutRequests = true; if (count > 0) { detachViewsFromParent(start, count); mRecycler.removeSkippedScrap(); } // invalidate before moving the children to avoid unnecessary invalidate // calls to bubble up from the children all the way to the top if (!awakenScrollBars()) { invalidate(); } offsetChildrenLeftAndRightUnhide(incrementalDeltaX); if (toRight) { mFirstPosition += count; } final int absIncrementalDeltaX = Math.abs(incrementalDeltaX); if (spaceToLeft < absIncrementalDeltaX || spaceToRight < absIncrementalDeltaX) { fillGap(toRight); } 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.appunite.list.AbsHorizontalListView.java
void positionSelector(int position, View sel) { if (position != INVALID_POSITION) { mSelectorPosition = position;/*from ww w . ja va2 s.c o m*/ } final Rect selectorRect = mSelectorRect; selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom()); if (sel instanceof SelectionBoundsAdjuster) { ((SelectionBoundsAdjuster) sel).adjustListItemSelectionBounds(selectorRect); } positionSelector(selectorRect.left, selectorRect.top, selectorRect.right, selectorRect.bottom); final boolean isChildViewEnabled = mIsChildViewEnabled; if (sel.isEnabled() != isChildViewEnabled) { mIsChildViewEnabled = !isChildViewEnabled; if (getSelectedItemPosition() != INVALID_POSITION) { refreshDrawableState(); } } }
From source file:com.appunite.list.AbsHorizontalListView.java
/** * Attempt to bring the selection back if the user is switching from touch * to trackball mode/*from w w w .java 2s . co m*/ * @return Whether selection was set to something. */ boolean resurrectSelection() { final int childCount = getChildCount(); if (childCount <= 0) { return false; } int selectedLeft = 0; int selectedPos; int childrenLeft = mListPadding.left; int childrenRight = getRight() - getLeft() - mListPadding.right; final int firstPosition = mFirstPosition; final int toPosition = mResurrectToPosition; boolean toRight = true; if (toPosition >= firstPosition && toPosition < firstPosition + childCount) { selectedPos = toPosition; final View selected = getChildAt(selectedPos - mFirstPosition); selectedLeft = selected.getLeft(); int selectedRight = selected.getRight(); // We are scrolled, don't get in the fade if (selectedLeft < childrenLeft) { selectedLeft = childrenLeft + getHorizontalFadingEdgeLength(); } else if (selectedRight > childrenRight) { selectedLeft = childrenRight - selected.getMeasuredWidth() - getHorizontalFadingEdgeLength(); } } else { if (toPosition < firstPosition) { // Default to selecting whatever is first selectedPos = firstPosition; for (int i = 0; i < childCount; i++) { final View v = getChildAt(i); final int left = v.getLeft(); if (i == 0) { // Remember the position of the first item selectedLeft = left; // See if we are scrolled at all if (firstPosition > 0 || left < childrenLeft) { // If we are scrolled, don't select anything that is // in the fade region childrenLeft += getHorizontalFadingEdgeLength(); } } if (left >= childrenLeft) { // Found a view whose left is fully visisble selectedPos = firstPosition + i; selectedLeft = left; break; } } } else { final int itemCount = mItemCount; toRight = false; selectedPos = firstPosition + childCount - 1; for (int i = childCount - 1; i >= 0; i--) { final View v = getChildAt(i); final int left = v.getLeft(); final int right = v.getRight(); if (i == childCount - 1) { selectedLeft = left; if (firstPosition + childCount < itemCount || right > childrenRight) { childrenRight -= getHorizontalFadingEdgeLength(); } } if (right <= childrenRight) { selectedPos = firstPosition + i; selectedLeft = left; break; } } } } mResurrectToPosition = INVALID_POSITION; removeCallbacks(mFlingRunnable); if (mPositionScroller != null) { mPositionScroller.stop(); } mTouchMode = TOUCH_MODE_REST; clearScrollingCache(); mSpecificLeft = selectedLeft; selectedPos = lookForSelectablePosition(selectedPos, toRight); if (selectedPos >= firstPosition && selectedPos <= getLastVisiblePosition()) { mLayoutMode = LAYOUT_SPECIFIC; updateSelectorState(); setSelectionInt(selectedPos); invokeOnItemScrollListener(); } else { selectedPos = INVALID_POSITION; } reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); return selectedPos >= 0; }
From source file:com.appunite.list.AbsHorizontalListView.java
@Override protected void handleDataChanged() { int count = mItemCount; int lastHandledItemCount = mLastHandledItemCount; mLastHandledItemCount = mItemCount;/*from www . j a v a 2s . c o m*/ if (mChoiceMode != CHOICE_MODE_NONE && mAdapter != null && mAdapter.hasStableIds()) { confirmCheckedPositionsById(); } // TODO: In the future we can recycle these views based on stable ID instead. mRecycler.clearTransientStateViews(); if (count > 0) { int newPos; int selectablePos; // Find the row we are supposed to sync to if (mNeedSync) { // Update this first, since setNextSelectedPositionInt inspects it mNeedSync = false; mPendingSync = null; if (mTranscriptMode == TRANSCRIPT_MODE_ALWAYS_SCROLL) { mLayoutMode = LAYOUT_FORCE_RIGHT; return; } else if (mTranscriptMode == TRANSCRIPT_MODE_NORMAL) { if (mForceTranscriptScroll) { mForceTranscriptScroll = false; mLayoutMode = LAYOUT_FORCE_RIGHT; return; } final int childCount = getChildCount(); final int listRight = getWidth() - getPaddingRight(); final View lastChild = getChildAt(childCount - 1); final int lastRight = lastChild != null ? lastChild.getRight() : listRight; if (mFirstPosition + childCount >= lastHandledItemCount && lastRight <= listRight) { mLayoutMode = LAYOUT_FORCE_RIGHT; return; } // Something new came in and we didn't scroll; give the user a clue that // there's something new. awakenScrollBars(); } switch (mSyncMode) { case SYNC_SELECTED_POSITION: if (isInTouchMode()) { // We saved our state when not in touch mode. (We know this because // mSyncMode is SYNC_SELECTED_POSITION.) Now we are trying to // restore in touch mode. Just leave mSyncPosition as it is (possibly // adjusting if the available range changed) and return. mLayoutMode = LAYOUT_SYNC; mSyncPosition = Math.min(Math.max(0, mSyncPosition), count - 1); return; } else { // See if we can find a position in the new data with the same // id as the old selection. This will change mSyncPosition. newPos = findSyncPosition(); if (newPos >= 0) { // Found it. Now verify that new selection is still selectable selectablePos = lookForSelectablePosition(newPos, true); if (selectablePos == newPos) { // Same row id is selected mSyncPosition = newPos; if (mSyncWidth == getWidth()) { // If we are at the same width as when we saved state, try // to restore the scroll position too. mLayoutMode = LAYOUT_SYNC; } else { // We are not the same width as when the selection was saved, so // don't try to restore the exact position mLayoutMode = LAYOUT_SET_SELECTION; } // Restore selection setNextSelectedPositionInt(newPos); return; } } } break; case SYNC_FIRST_POSITION: // Leave mSyncPosition as it is -- just pin to available range mLayoutMode = LAYOUT_SYNC; mSyncPosition = Math.min(Math.max(0, mSyncPosition), count - 1); return; } } if (!isInTouchMode()) { // We couldn't find matching data -- try to use the same position newPos = getSelectedItemPosition(); // Pin position to the available range if (newPos >= count) { newPos = count - 1; } if (newPos < 0) { newPos = 0; } // Make sure we select something selectable -- first look down selectablePos = lookForSelectablePosition(newPos, true); if (selectablePos >= 0) { setNextSelectedPositionInt(selectablePos); return; } else { // Looking down didn't work -- try looking up selectablePos = lookForSelectablePosition(newPos, false); if (selectablePos >= 0) { setNextSelectedPositionInt(selectablePos); return; } } } else { // We already know where we want to resurrect the selection if (mResurrectToPosition >= 0) { return; } } } // Nothing is selected. Give up and reset everything. mLayoutMode = mStackFromRight ? LAYOUT_FORCE_RIGHT : LAYOUT_FORCE_LEFT; mSelectedPosition = INVALID_POSITION; mSelectedColId = INVALID_COL_ID; mNextSelectedPosition = INVALID_POSITION; mNextSelectedColId = INVALID_COL_ID; mNeedSync = false; mPendingSync = null; mSelectorPosition = INVALID_POSITION; checkSelectionChanged(); }
From source file:com.appunite.list.AbsHorizontalListView.java
@Override protected int computeHorizontalScrollExtent() { final int count = getChildCount(); if (count > 0) { if (mSmoothScrollbarEnabled) { int extent = count * 100; View view = getChildAt(0); final int left = view.getLeft(); int width = view.getWidth(); if (width > 0) { extent += (left * 100) / width; }/*from w w w.j a va 2s. com*/ view = getChildAt(count - 1); final int right = view.getRight(); width = view.getWidth(); if (width > 0) { extent -= ((right - getWidth()) * 100) / width; } return extent; } else { return 1; } } return 0; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private int findMotionRowOrColumn(int motionPos) { int childCount = getChildCount(); if (childCount == 0) { return INVALID_POSITION; }//from w ww . ja va 2 s .c o m for (int i = 0; i < childCount; i++) { View v = getChildAt(i); if ((mIsVertical && motionPos <= v.getBottom()) || (!mIsVertical && motionPos <= v.getRight())) { return mFirstPosition + i; } } return INVALID_POSITION; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private void correctTooLow(int childCount) { // First see if the first item is visible. If it is not, it is OK for the // bottom of the list to be pushed down. if (mFirstPosition != 0 || childCount == 0) { return;/*from ww w . j av a2s. c o m*/ } final View first = getChildAt(0); final int firstStart = (mIsVertical ? first.getTop() : first.getLeft()); final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int end; if (mIsVertical) { end = getHeight() - getPaddingBottom(); } else { end = getWidth() - getPaddingRight(); } // This is how far the start edge of the first view is from the start of the // drawable area int startOffset = firstStart - start; View last = getChildAt(childCount - 1); int lastEnd = (mIsVertical ? last.getBottom() : last.getRight()); int lastPosition = mFirstPosition + childCount - 1; // Make sure we are 1) Too low, and 2) Either there are more columns/rows below the // last column/row or the last column/row is scrolled off the end of the // drawable area if (startOffset > 0) { if (lastPosition < mItemCount - 1 || lastEnd > end) { if (lastPosition == mItemCount - 1) { // Don't pull the bottom too far up startOffset = Math.min(startOffset, lastEnd - end); } // Move everything up offsetChildren(-startOffset); if (lastPosition < mItemCount - 1) { lastEnd = (mIsVertical ? last.getBottom() : last.getRight()); // Fill the gap that was opened below the last position with more rows, if // possible fillAfter(lastPosition + 1, lastEnd + mItemMargin); // Close up the remaining gap adjustViewsStartOrEnd(); } } else if (lastPosition == mItemCount - 1) { adjustViewsStartOrEnd(); } } }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private void positionSelector(int position, View selected) { if (position != INVALID_POSITION) { mSelectorPosition = position;// w ww.j av a2 s. c o m } mSelectorRect.set(selected.getLeft(), selected.getTop(), selected.getRight(), selected.getBottom()); final boolean isChildViewEnabled = mIsChildViewEnabled; if (selected.isEnabled() != isChildViewEnabled) { mIsChildViewEnabled = !isChildViewEnabled; if (getSelectedItemPosition() != INVALID_POSITION) { refreshDrawableState(); } } }
From source file:com.mist.sciryl.app.views.TwoWayView.java
void fillGap(boolean down) { final int childCount = getChildCount(); if (down) {//ww w.j av a 2 s . co m final int paddingStart = (mIsVertical ? getPaddingTop() : getPaddingLeft()); final int lastEnd; View lastChild = getChildAt(childCount - 1); if (mIsVertical) { lastEnd = lastChild.getBottom(); } else { lastEnd = lastChild.getRight(); } final int offset = (childCount > 0 ? lastEnd + mItemMargin : paddingStart); fillAfter(mFirstPosition + childCount, offset); correctTooHigh(getChildCount()); } else { final int end; final int firstStart; if (mIsVertical) { end = getHeight() - getPaddingBottom(); firstStart = getChildAt(0).getTop(); } else { end = getWidth() - getPaddingRight(); firstStart = getChildAt(0).getLeft(); } final int offset = (childCount > 0 ? firstStart - mItemMargin : end); fillBefore(mFirstPosition - 1, offset); correctTooLow(getChildCount()); } }