Loading core/java/android/widget/AdapterViewAnimator.java +38 −27 Original line number Diff line number Diff line Loading @@ -69,12 +69,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> * The number of views that the {@link AdapterViewAnimator} keeps as children at any * given time (not counting views that are pending removal, see {@link #mPreviousViews}). */ int mNumActiveViews = 1; int mMaxNumActiveViews = 1; /** * Map of the children of the {@link AdapterViewAnimator}. */ private HashMap<Integer, ViewAndIndex> mViewsMap = new HashMap<Integer, ViewAndIndex>(); HashMap<Integer, ViewAndIndex> mViewsMap = new HashMap<Integer, ViewAndIndex>(); /** * List of views pending removal from the {@link AdapterViewAnimator} Loading Loading @@ -141,8 +141,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> ObjectAnimator mInAnimation; ObjectAnimator mOutAnimation; private ArrayList<View> mViewsToBringToFront; private static final int DEFAULT_ANIMATION_DURATION = 200; public AdapterViewAnimator(Context context) { Loading Loading @@ -188,10 +186,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> private void initViewAnimator() { mMainQueue = new Handler(Looper.myLooper()); mPreviousViews = new ArrayList<Integer>(); mViewsToBringToFront = new ArrayList<View>(); } private class ViewAndIndex { class ViewAndIndex { ViewAndIndex(View v, int i) { view = v; index = i; Loading @@ -217,7 +214,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> if (activeOffset > numVisibleViews - 1) { // Throw an exception here. } mNumActiveViews = numVisibleViews; mMaxNumActiveViews = numVisibleViews; mActiveOffset = activeOffset; mPreviousViews.clear(); mViewsMap.clear(); Loading Loading @@ -266,10 +263,10 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> public void setDisplayedChild(int whichChild) { if (mAdapter != null) { mWhichChild = whichChild; if (whichChild >= mAdapter.getCount()) { mWhichChild = mLoopViews ? 0 : mAdapter.getCount() - 1; if (whichChild >= getWindowSize()) { mWhichChild = mLoopViews ? 0 : getWindowSize() - 1; } else if (whichChild < 0) { mWhichChild = mLoopViews ? mAdapter.getCount() - 1 : 0; mWhichChild = mLoopViews ? getWindowSize() - 1 : 0; } boolean hasFocus = getFocusedChild() != null; Loading Loading @@ -327,7 +324,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> showOnly(childIndex, animate, false); } private int modulo(int pos, int size) { int modulo(int pos, int size) { if (size > 0) { return (size + (pos % size)) % size; } else { Loading @@ -342,9 +339,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> * @return View at this index, null if the index is outside the bounds */ View getViewAtRelativeIndex(int relativeIndex) { if (relativeIndex >= 0 && relativeIndex <= mNumActiveViews - 1 && mAdapter != null) { int adapterCount = mAdapter.getCount(); int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, adapterCount); if (relativeIndex >= 0 && relativeIndex <= getNumActiveViews() - 1 && mAdapter != null) { int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, getWindowSize()); if (mViewsMap.get(i) != null) { return mViewsMap.get(i).view; } Loading @@ -352,6 +348,27 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> return null; } int getNumActiveViews() { if (mAdapter != null) { return Math.min(mAdapter.getCount() + 1, mMaxNumActiveViews); } else { return mMaxNumActiveViews; } } int getWindowSize() { if (mAdapter != null) { int adapterCount = mAdapter.getCount(); if (adapterCount <= getNumActiveViews() && mLoopViews) { return adapterCount*mMaxNumActiveViews; } else { return adapterCount; } } else { return 0; } } LayoutParams createOrReuseLayoutParams(View v) { final ViewGroup.LayoutParams currentLp = v.getLayoutParams(); if (currentLp instanceof ViewGroup.LayoutParams) { Loading @@ -363,7 +380,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> void refreshChildren() { for (int i = mCurrentWindowStart; i <= mCurrentWindowEnd; i++) { int index = modulo(i, mNumActiveViews); int index = modulo(i, mMaxNumActiveViews); // get the fresh child from the adapter View updatedChild = mAdapter.getView(i, null, this); Loading Loading @@ -412,7 +429,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } mPreviousViews.clear(); int newWindowStartUnbounded = childIndex - mActiveOffset; int newWindowEndUnbounded = newWindowStartUnbounded + mNumActiveViews - 1; int newWindowEndUnbounded = newWindowStartUnbounded + getNumActiveViews() - 1; int newWindowStart = Math.max(0, newWindowStartUnbounded); int newWindowEnd = Math.min(adapterCount - 1, newWindowEndUnbounded); Loading @@ -420,8 +437,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> newWindowStart = newWindowStartUnbounded; newWindowEnd = newWindowEndUnbounded; } int rangeStart = modulo(newWindowStart, adapterCount); int rangeEnd = modulo(newWindowEnd, adapterCount); int rangeStart = modulo(newWindowStart, getWindowSize()); int rangeEnd = modulo(newWindowEnd, getWindowSize()); boolean wrap = false; if (rangeStart > rangeEnd) { Loading Loading @@ -450,11 +467,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } // If the window has changed if (!(newWindowStart == mCurrentWindowStart && newWindowEnd == mCurrentWindowEnd)) { if (!(newWindowStart == mCurrentWindowStart && newWindowEnd == mCurrentWindowEnd && newWindowStartUnbounded == mCurrentWindowStartUnbounded)) { // Run through the indices in the new range for (int i = newWindowStart; i <= newWindowEnd; i++) { int index = modulo(i, adapterCount); int index = modulo(i, getWindowSize()); int oldRelativeIndex; if (mViewsMap.containsKey(index)) { oldRelativeIndex = mViewsMap.get(index).index; Loading Loading @@ -494,13 +512,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } mViewsMap.get(index).view.bringToFront(); } for (int i = 0; i < mViewsToBringToFront.size(); i++) { View v = mViewsToBringToFront.get(i); v.bringToFront(); } mViewsToBringToFront.clear(); mCurrentWindowStart = newWindowStart; mCurrentWindowEnd = newWindowEnd; mCurrentWindowStartUnbounded = newWindowStartUnbounded; Loading core/java/android/widget/StackView.java +36 −28 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class StackView extends AdapterViewAnimator { } private void initStackView() { configureViewAnimator(NUM_ACTIVE_VIEWS, NUM_ACTIVE_VIEWS - 2); configureViewAnimator(NUM_ACTIVE_VIEWS, 1); setStaticTransformationsEnabled(true); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); mTouchSlop = configuration.getScaledTouchSlop(); Loading Loading @@ -165,7 +165,7 @@ public class StackView extends AdapterViewAnimator { * Animate the views between different relative indexes within the {@link AdapterViewAnimator} */ void animateViewForTransition(int fromIndex, int toIndex, View view) { if (fromIndex == -1 && toIndex == 0) { if (fromIndex == -1 && toIndex != 0) { // Fade item in if (view.getAlpha() == 1) { view.setAlpha(0); Loading @@ -175,7 +175,7 @@ public class StackView extends AdapterViewAnimator { ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f); fadeIn.setDuration(DEFAULT_ANIMATION_DURATION); fadeIn.start(); } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) { } else if (fromIndex == 0 && toIndex == 1) { // Slide item in view.setVisibility(VISIBLE); Loading @@ -189,7 +189,7 @@ public class StackView extends AdapterViewAnimator { pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) { } else if (fromIndex == 1 && toIndex == 0) { // Slide item out int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity)); Loading @@ -201,7 +201,7 @@ public class StackView extends AdapterViewAnimator { pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) { } else if (fromIndex == -1 && toIndex == 0) { // Make sure this view that is "waiting in the wings" is invisible view.setAlpha(0.0f); view.setVisibility(INVISIBLE); Loading @@ -223,9 +223,10 @@ public class StackView extends AdapterViewAnimator { private void transformViewAtIndex(int index, View view) { float maxPerpectiveShift = mMeasuredHeight * PERSPECTIVE_SHIFT_FACTOR; if (index == mNumActiveViews -1) index--; index = mMaxNumActiveViews - index - 1; if (index == mMaxNumActiveViews - 1) index--; float r = (index * 1.0f) / (mNumActiveViews - 2); float r = (index * 1.0f) / (mMaxNumActiveViews - 2); float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r); PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scale); Loading @@ -245,8 +246,20 @@ public class StackView extends AdapterViewAnimator { pa.start(); } @Override void showOnly(int childIndex, boolean animate, boolean onLayout) { super.showOnly(childIndex, animate, onLayout); // Here we need to make sure that the z-order of the children is correct for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) { int index = modulo(i, getWindowSize()); View v = mViewsMap.get(index).view; if (v != null) v.bringToFront(); } } private void updateChildTransforms() { for (int i = 0; i < mNumActiveViews - 1; i++) { for (int i = 0; i < getNumActiveViews(); i++) { View v = getViewAtRelativeIndex(i); if (v != null) { transformViewAtIndex(i, v); Loading Loading @@ -341,19 +354,17 @@ public class StackView extends AdapterViewAnimator { int activeIndex; if (mStackMode == ITEMS_SLIDE_UP) { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 1 : mNumActiveViews - 2; activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1; } else { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 2 : mNumActiveViews - 1; activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0; } if (mLoopViews) { mStackSlider.setMode(StackSlider.NORMAL_MODE); } else if (mCurrentWindowStartUnbounded + activeIndex == 0) { } else if (mCurrentWindowStartUnbounded + activeIndex == -1) { activeIndex++; mStackSlider.setMode(StackSlider.BEGINNING_OF_STACK_MODE); } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount()) { activeIndex--; } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) { mStackSlider.setMode(StackSlider.END_OF_STACK_MODE); } else { mStackSlider.setMode(StackSlider.NORMAL_MODE); Loading Loading @@ -439,8 +450,7 @@ public class StackView extends AdapterViewAnimator { final int pointerId = ev.getPointerId(activePointerIndex); if (pointerId == mActivePointerId) { int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 1 : mNumActiveViews - 2; int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1; View v = getViewAtRelativeIndex(activeViewIndex); if (v == null) return; Loading Loading @@ -498,18 +508,18 @@ public class StackView extends AdapterViewAnimator { && mStackSlider.mMode == StackSlider.NORMAL_MODE) { // Swipe threshold exceeded, swipe down if (mStackMode == ITEMS_SLIDE_UP) { showNext(); } else { showPrevious(); } else { showNext(); } mHighlight.bringToFront(); } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP && mStackSlider.mMode == StackSlider.NORMAL_MODE) { // Swipe threshold exceeded, swipe up if (mStackMode == ITEMS_SLIDE_UP) { showPrevious(); } else { showNext(); } else { showPrevious(); } mHighlight.bringToFront(); Loading Loading @@ -643,13 +653,13 @@ public class StackView extends AdapterViewAnimator { mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r)); mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r)); break; case BEGINNING_OF_STACK_MODE: case END_OF_STACK_MODE: r = r * 0.2f; viewLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount)); highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount)); mHighlight.setAlpha(highlightAlphaInterpolator(r)); break; case END_OF_STACK_MODE: case BEGINNING_OF_STACK_MODE: r = (1-r) * 0.2f; viewLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount)); highlightLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount)); Loading Loading @@ -735,13 +745,11 @@ public class StackView extends AdapterViewAnimator { public void onRemoteAdapterConnected() { super.onRemoteAdapterConnected(); // On first run, we want to set the stack to the end. if (mAdapter != null && mWhichChild == -1) { mWhichChild = mAdapter.getCount() - 1; if (mWhichChild == -1) { mWhichChild = 0; } if (mWhichChild >= 0) { setDisplayedChild(mWhichChild); } } LayoutParams createOrReuseLayoutParams(View v) { final ViewGroup.LayoutParams currentLp = v.getLayoutParams(); Loading Loading
core/java/android/widget/AdapterViewAnimator.java +38 −27 Original line number Diff line number Diff line Loading @@ -69,12 +69,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> * The number of views that the {@link AdapterViewAnimator} keeps as children at any * given time (not counting views that are pending removal, see {@link #mPreviousViews}). */ int mNumActiveViews = 1; int mMaxNumActiveViews = 1; /** * Map of the children of the {@link AdapterViewAnimator}. */ private HashMap<Integer, ViewAndIndex> mViewsMap = new HashMap<Integer, ViewAndIndex>(); HashMap<Integer, ViewAndIndex> mViewsMap = new HashMap<Integer, ViewAndIndex>(); /** * List of views pending removal from the {@link AdapterViewAnimator} Loading Loading @@ -141,8 +141,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> ObjectAnimator mInAnimation; ObjectAnimator mOutAnimation; private ArrayList<View> mViewsToBringToFront; private static final int DEFAULT_ANIMATION_DURATION = 200; public AdapterViewAnimator(Context context) { Loading Loading @@ -188,10 +186,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> private void initViewAnimator() { mMainQueue = new Handler(Looper.myLooper()); mPreviousViews = new ArrayList<Integer>(); mViewsToBringToFront = new ArrayList<View>(); } private class ViewAndIndex { class ViewAndIndex { ViewAndIndex(View v, int i) { view = v; index = i; Loading @@ -217,7 +214,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> if (activeOffset > numVisibleViews - 1) { // Throw an exception here. } mNumActiveViews = numVisibleViews; mMaxNumActiveViews = numVisibleViews; mActiveOffset = activeOffset; mPreviousViews.clear(); mViewsMap.clear(); Loading Loading @@ -266,10 +263,10 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> public void setDisplayedChild(int whichChild) { if (mAdapter != null) { mWhichChild = whichChild; if (whichChild >= mAdapter.getCount()) { mWhichChild = mLoopViews ? 0 : mAdapter.getCount() - 1; if (whichChild >= getWindowSize()) { mWhichChild = mLoopViews ? 0 : getWindowSize() - 1; } else if (whichChild < 0) { mWhichChild = mLoopViews ? mAdapter.getCount() - 1 : 0; mWhichChild = mLoopViews ? getWindowSize() - 1 : 0; } boolean hasFocus = getFocusedChild() != null; Loading Loading @@ -327,7 +324,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> showOnly(childIndex, animate, false); } private int modulo(int pos, int size) { int modulo(int pos, int size) { if (size > 0) { return (size + (pos % size)) % size; } else { Loading @@ -342,9 +339,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> * @return View at this index, null if the index is outside the bounds */ View getViewAtRelativeIndex(int relativeIndex) { if (relativeIndex >= 0 && relativeIndex <= mNumActiveViews - 1 && mAdapter != null) { int adapterCount = mAdapter.getCount(); int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, adapterCount); if (relativeIndex >= 0 && relativeIndex <= getNumActiveViews() - 1 && mAdapter != null) { int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, getWindowSize()); if (mViewsMap.get(i) != null) { return mViewsMap.get(i).view; } Loading @@ -352,6 +348,27 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> return null; } int getNumActiveViews() { if (mAdapter != null) { return Math.min(mAdapter.getCount() + 1, mMaxNumActiveViews); } else { return mMaxNumActiveViews; } } int getWindowSize() { if (mAdapter != null) { int adapterCount = mAdapter.getCount(); if (adapterCount <= getNumActiveViews() && mLoopViews) { return adapterCount*mMaxNumActiveViews; } else { return adapterCount; } } else { return 0; } } LayoutParams createOrReuseLayoutParams(View v) { final ViewGroup.LayoutParams currentLp = v.getLayoutParams(); if (currentLp instanceof ViewGroup.LayoutParams) { Loading @@ -363,7 +380,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> void refreshChildren() { for (int i = mCurrentWindowStart; i <= mCurrentWindowEnd; i++) { int index = modulo(i, mNumActiveViews); int index = modulo(i, mMaxNumActiveViews); // get the fresh child from the adapter View updatedChild = mAdapter.getView(i, null, this); Loading Loading @@ -412,7 +429,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } mPreviousViews.clear(); int newWindowStartUnbounded = childIndex - mActiveOffset; int newWindowEndUnbounded = newWindowStartUnbounded + mNumActiveViews - 1; int newWindowEndUnbounded = newWindowStartUnbounded + getNumActiveViews() - 1; int newWindowStart = Math.max(0, newWindowStartUnbounded); int newWindowEnd = Math.min(adapterCount - 1, newWindowEndUnbounded); Loading @@ -420,8 +437,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> newWindowStart = newWindowStartUnbounded; newWindowEnd = newWindowEndUnbounded; } int rangeStart = modulo(newWindowStart, adapterCount); int rangeEnd = modulo(newWindowEnd, adapterCount); int rangeStart = modulo(newWindowStart, getWindowSize()); int rangeEnd = modulo(newWindowEnd, getWindowSize()); boolean wrap = false; if (rangeStart > rangeEnd) { Loading Loading @@ -450,11 +467,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } // If the window has changed if (!(newWindowStart == mCurrentWindowStart && newWindowEnd == mCurrentWindowEnd)) { if (!(newWindowStart == mCurrentWindowStart && newWindowEnd == mCurrentWindowEnd && newWindowStartUnbounded == mCurrentWindowStartUnbounded)) { // Run through the indices in the new range for (int i = newWindowStart; i <= newWindowEnd; i++) { int index = modulo(i, adapterCount); int index = modulo(i, getWindowSize()); int oldRelativeIndex; if (mViewsMap.containsKey(index)) { oldRelativeIndex = mViewsMap.get(index).index; Loading Loading @@ -494,13 +512,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } mViewsMap.get(index).view.bringToFront(); } for (int i = 0; i < mViewsToBringToFront.size(); i++) { View v = mViewsToBringToFront.get(i); v.bringToFront(); } mViewsToBringToFront.clear(); mCurrentWindowStart = newWindowStart; mCurrentWindowEnd = newWindowEnd; mCurrentWindowStartUnbounded = newWindowStartUnbounded; Loading
core/java/android/widget/StackView.java +36 −28 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public class StackView extends AdapterViewAnimator { } private void initStackView() { configureViewAnimator(NUM_ACTIVE_VIEWS, NUM_ACTIVE_VIEWS - 2); configureViewAnimator(NUM_ACTIVE_VIEWS, 1); setStaticTransformationsEnabled(true); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); mTouchSlop = configuration.getScaledTouchSlop(); Loading Loading @@ -165,7 +165,7 @@ public class StackView extends AdapterViewAnimator { * Animate the views between different relative indexes within the {@link AdapterViewAnimator} */ void animateViewForTransition(int fromIndex, int toIndex, View view) { if (fromIndex == -1 && toIndex == 0) { if (fromIndex == -1 && toIndex != 0) { // Fade item in if (view.getAlpha() == 1) { view.setAlpha(0); Loading @@ -175,7 +175,7 @@ public class StackView extends AdapterViewAnimator { ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f); fadeIn.setDuration(DEFAULT_ANIMATION_DURATION); fadeIn.start(); } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) { } else if (fromIndex == 0 && toIndex == 1) { // Slide item in view.setVisibility(VISIBLE); Loading @@ -189,7 +189,7 @@ public class StackView extends AdapterViewAnimator { pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) { } else if (fromIndex == 1 && toIndex == 0) { // Slide item out int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity)); Loading @@ -201,7 +201,7 @@ public class StackView extends AdapterViewAnimator { pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) { } else if (fromIndex == -1 && toIndex == 0) { // Make sure this view that is "waiting in the wings" is invisible view.setAlpha(0.0f); view.setVisibility(INVISIBLE); Loading @@ -223,9 +223,10 @@ public class StackView extends AdapterViewAnimator { private void transformViewAtIndex(int index, View view) { float maxPerpectiveShift = mMeasuredHeight * PERSPECTIVE_SHIFT_FACTOR; if (index == mNumActiveViews -1) index--; index = mMaxNumActiveViews - index - 1; if (index == mMaxNumActiveViews - 1) index--; float r = (index * 1.0f) / (mNumActiveViews - 2); float r = (index * 1.0f) / (mMaxNumActiveViews - 2); float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r); PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scale); Loading @@ -245,8 +246,20 @@ public class StackView extends AdapterViewAnimator { pa.start(); } @Override void showOnly(int childIndex, boolean animate, boolean onLayout) { super.showOnly(childIndex, animate, onLayout); // Here we need to make sure that the z-order of the children is correct for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) { int index = modulo(i, getWindowSize()); View v = mViewsMap.get(index).view; if (v != null) v.bringToFront(); } } private void updateChildTransforms() { for (int i = 0; i < mNumActiveViews - 1; i++) { for (int i = 0; i < getNumActiveViews(); i++) { View v = getViewAtRelativeIndex(i); if (v != null) { transformViewAtIndex(i, v); Loading Loading @@ -341,19 +354,17 @@ public class StackView extends AdapterViewAnimator { int activeIndex; if (mStackMode == ITEMS_SLIDE_UP) { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 1 : mNumActiveViews - 2; activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1; } else { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 2 : mNumActiveViews - 1; activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0; } if (mLoopViews) { mStackSlider.setMode(StackSlider.NORMAL_MODE); } else if (mCurrentWindowStartUnbounded + activeIndex == 0) { } else if (mCurrentWindowStartUnbounded + activeIndex == -1) { activeIndex++; mStackSlider.setMode(StackSlider.BEGINNING_OF_STACK_MODE); } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount()) { activeIndex--; } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) { mStackSlider.setMode(StackSlider.END_OF_STACK_MODE); } else { mStackSlider.setMode(StackSlider.NORMAL_MODE); Loading Loading @@ -439,8 +450,7 @@ public class StackView extends AdapterViewAnimator { final int pointerId = ev.getPointerId(activePointerIndex); if (pointerId == mActivePointerId) { int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 1 : mNumActiveViews - 2; int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1; View v = getViewAtRelativeIndex(activeViewIndex); if (v == null) return; Loading Loading @@ -498,18 +508,18 @@ public class StackView extends AdapterViewAnimator { && mStackSlider.mMode == StackSlider.NORMAL_MODE) { // Swipe threshold exceeded, swipe down if (mStackMode == ITEMS_SLIDE_UP) { showNext(); } else { showPrevious(); } else { showNext(); } mHighlight.bringToFront(); } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP && mStackSlider.mMode == StackSlider.NORMAL_MODE) { // Swipe threshold exceeded, swipe up if (mStackMode == ITEMS_SLIDE_UP) { showPrevious(); } else { showNext(); } else { showPrevious(); } mHighlight.bringToFront(); Loading Loading @@ -643,13 +653,13 @@ public class StackView extends AdapterViewAnimator { mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r)); mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r)); break; case BEGINNING_OF_STACK_MODE: case END_OF_STACK_MODE: r = r * 0.2f; viewLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount)); highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount)); mHighlight.setAlpha(highlightAlphaInterpolator(r)); break; case END_OF_STACK_MODE: case BEGINNING_OF_STACK_MODE: r = (1-r) * 0.2f; viewLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount)); highlightLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount)); Loading Loading @@ -735,13 +745,11 @@ public class StackView extends AdapterViewAnimator { public void onRemoteAdapterConnected() { super.onRemoteAdapterConnected(); // On first run, we want to set the stack to the end. if (mAdapter != null && mWhichChild == -1) { mWhichChild = mAdapter.getCount() - 1; if (mWhichChild == -1) { mWhichChild = 0; } if (mWhichChild >= 0) { setDisplayedChild(mWhichChild); } } LayoutParams createOrReuseLayoutParams(View v) { final ViewGroup.LayoutParams currentLp = v.getLayoutParams(); Loading