public void setDisplayedViewIndex(int i) { if (0 <= i && i < mAdapter.getCount()) { onMoveOffChild(mCurrent); mCurrent = i; onMoveToChild(i); mResetLayout = true; requestLayout(); } }
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); View cv = mChildViews.get(mCurrent); Point cvOffset; if (!mResetLayout) { // Move to next or previous if current is sufficiently off center if (cv != null) { cvOffset = subScreenSizeOffset(cv); // cv.getRight() may be out of date with the current scale // so add left to the measured width for the correct position if (cv.getLeft() + cv.getMeasuredWidth() + cvOffset.x + GAP / 2 + mXScroll < getWidth() / 2 && mCurrent + 1 < mAdapter.getCount()) { postUnsettle(cv); // post to invoke test for end of animation // where we must set hq area for the new current view post(this); onMoveOffChild(mCurrent); mCurrent++; onMoveToChild(mCurrent); } if (cv.getLeft() - cvOffset.x - GAP / 2 + mXScroll >= getWidth() / 2 && mCurrent > 0) { postUnsettle(cv); // post to invoke test for end of animation // where we must set hq area for the new current view post(this); onMoveOffChild(mCurrent); mCurrent--; onMoveToChild(mCurrent); } } // Remove not needed children and hold them for reuse int numChildren = mChildViews.size(); int childIndices[] = new int[numChildren]; for (int i = 0; i < numChildren; i++) childIndices[i] = mChildViews.keyAt(i); for (int i = 0; i < numChildren; i++) { int ai = childIndices[i]; if (ai < mCurrent - 1 || ai > mCurrent + 1) { View v = mChildViews.get(ai); onNotInUse(v); mViewCache.add(v); removeViewInLayout(v); mChildViews.remove(ai); } } } else { mResetLayout = false; mXScroll = mYScroll = 0; // Remove all children and hold them for reuse int numChildren = mChildViews.size(); for (int i = 0; i < numChildren; i++) { View v = mChildViews.valueAt(i); onNotInUse(v); mViewCache.add(v); removeViewInLayout(v); } mChildViews.clear(); // post to ensure generation of hq area post(this); } // Ensure current view is present int cvLeft, cvRight, cvTop, cvBottom; boolean notPresent = (mChildViews.get(mCurrent) == null); cv = getOrCreateChild(mCurrent); // When the view is sub-screen-size in either dimension we // offset it to center within the screen area, and to keep // the views spaced out cvOffset = subScreenSizeOffset(cv); if (notPresent) { // Main item not already present. Just place it top left cvLeft = cvOffset.x; cvTop = cvOffset.y; } else { // Main item already present. Adjust by scroll offsets cvLeft = cv.getLeft() + mXScroll; cvTop = cv.getTop() + mYScroll; } // Scroll values have been accounted for mXScroll = mYScroll = 0; cvRight = cvLeft + cv.getMeasuredWidth(); cvBottom = cvTop + cv.getMeasuredHeight(); if (!mUserInteracting && mScroller.isFinished()) { Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom)); cvRight += corr.x; cvLeft += corr.x; cvTop += corr.y; cvBottom += corr.y; } else if (cv.getMeasuredHeight() <= getHeight()) { // When the current view is as small as the screen in height, clamp // it vertically Point corr = getCorrection(getScrollBounds(cvLeft, cvTop, cvRight, cvBottom)); cvTop += corr.y; cvBottom += corr.y; } cv.layout(cvLeft, cvTop, cvRight, cvBottom); if (mCurrent > 0) { View lv = getOrCreateChild(mCurrent - 1); Point leftOffset = subScreenSizeOffset(lv); int gap = leftOffset.x + GAP + cvOffset.x; lv.layout( cvLeft - lv.getMeasuredWidth() - gap, (cvBottom + cvTop - lv.getMeasuredHeight()) / 2, cvLeft - gap, (cvBottom + cvTop + lv.getMeasuredHeight()) / 2); } if (mCurrent + 1 < mAdapter.getCount()) { View rv = getOrCreateChild(mCurrent + 1); Point rightOffset = subScreenSizeOffset(rv); int gap = cvOffset.x + GAP + rightOffset.x; rv.layout( cvRight + gap, (cvBottom + cvTop - rv.getMeasuredHeight()) / 2, cvRight + rv.getMeasuredWidth() + gap, (cvBottom + cvTop + rv.getMeasuredHeight()) / 2); } invalidate(); }