Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96d8d563 authored by Adam Cohen's avatar Adam Cohen
Browse files

Fixing the case of less than or equal to 5 items in StackView

Change-Id: I9226fe8343902e06e2f4b04837e232f1744786a8
parent a8cbdb9a
Loading
Loading
Loading
Loading
+38 −27
Original line number Original line Diff line number Diff line
@@ -69,12 +69,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
     * The number of views that the {@link AdapterViewAnimator} keeps as children at any
     * 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}).
     * 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}.
     * 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}
     * List of views pending removal from the {@link AdapterViewAnimator}
@@ -141,8 +141,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
    ObjectAnimator mInAnimation;
    ObjectAnimator mInAnimation;
    ObjectAnimator mOutAnimation;
    ObjectAnimator mOutAnimation;


    private  ArrayList<View> mViewsToBringToFront;

    private static final int DEFAULT_ANIMATION_DURATION = 200;
    private static final int DEFAULT_ANIMATION_DURATION = 200;


    public AdapterViewAnimator(Context context) {
    public AdapterViewAnimator(Context context) {
@@ -188,10 +186,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
    private void initViewAnimator() {
    private void initViewAnimator() {
        mMainQueue = new Handler(Looper.myLooper());
        mMainQueue = new Handler(Looper.myLooper());
        mPreviousViews = new ArrayList<Integer>();
        mPreviousViews = new ArrayList<Integer>();
        mViewsToBringToFront = new ArrayList<View>();
    }
    }


    private class ViewAndIndex {
    class ViewAndIndex {
        ViewAndIndex(View v, int i) {
        ViewAndIndex(View v, int i) {
            view = v;
            view = v;
            index = i;
            index = i;
@@ -217,7 +214,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
        if (activeOffset > numVisibleViews - 1) {
        if (activeOffset > numVisibleViews - 1) {
            // Throw an exception here.
            // Throw an exception here.
        }
        }
        mNumActiveViews = numVisibleViews;
        mMaxNumActiveViews = numVisibleViews;
        mActiveOffset = activeOffset;
        mActiveOffset = activeOffset;
        mPreviousViews.clear();
        mPreviousViews.clear();
        mViewsMap.clear();
        mViewsMap.clear();
@@ -266,10 +263,10 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
    public void setDisplayedChild(int whichChild) {
    public void setDisplayedChild(int whichChild) {
        if (mAdapter != null) {
        if (mAdapter != null) {
            mWhichChild = whichChild;
            mWhichChild = whichChild;
            if (whichChild >= mAdapter.getCount()) {
            if (whichChild >= getWindowSize()) {
                mWhichChild = mLoopViews ? 0 : mAdapter.getCount() - 1;
                mWhichChild = mLoopViews ? 0 : getWindowSize() - 1;
            } else if (whichChild < 0) {
            } else if (whichChild < 0) {
                mWhichChild = mLoopViews ? mAdapter.getCount() - 1 : 0;
                mWhichChild = mLoopViews ? getWindowSize() - 1 : 0;
            }
            }


            boolean hasFocus = getFocusedChild() != null;
            boolean hasFocus = getFocusedChild() != null;
@@ -327,7 +324,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
        showOnly(childIndex, animate, false);
        showOnly(childIndex, animate, false);
    }
    }


    private int modulo(int pos, int size) {
    int modulo(int pos, int size) {
        if (size > 0) {
        if (size > 0) {
            return (size + (pos % size)) % size;
            return (size + (pos % size)) % size;
        } else {
        } else {
@@ -342,9 +339,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
     * @return View at this index, null if the index is outside the bounds
     * @return View at this index, null if the index is outside the bounds
     */
     */
    View getViewAtRelativeIndex(int relativeIndex) {
    View getViewAtRelativeIndex(int relativeIndex) {
        if (relativeIndex >= 0 && relativeIndex <= mNumActiveViews - 1 && mAdapter != null) {
        if (relativeIndex >= 0 && relativeIndex <= getNumActiveViews() - 1 && mAdapter != null) {
            int adapterCount =  mAdapter.getCount();
            int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, getWindowSize());
            int i = modulo(mCurrentWindowStartUnbounded + relativeIndex, adapterCount);
            if (mViewsMap.get(i) != null) {
            if (mViewsMap.get(i) != null) {
                return mViewsMap.get(i).view;
                return mViewsMap.get(i).view;
            }
            }
@@ -352,6 +348,27 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
        return null;
        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) {
    LayoutParams createOrReuseLayoutParams(View v) {
        final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
        final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
        if (currentLp instanceof ViewGroup.LayoutParams) {
        if (currentLp instanceof ViewGroup.LayoutParams) {
@@ -363,7 +380,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>


    void refreshChildren() {
    void refreshChildren() {
        for (int i = mCurrentWindowStart; i <= mCurrentWindowEnd; i++) {
        for (int i = mCurrentWindowStart; i <= mCurrentWindowEnd; i++) {
            int index = modulo(i, mNumActiveViews);
            int index = modulo(i, mMaxNumActiveViews);


            // get the fresh child from the adapter
            // get the fresh child from the adapter
            View updatedChild = mAdapter.getView(i, null, this);
            View updatedChild = mAdapter.getView(i, null, this);
@@ -412,7 +429,7 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
        }
        }
        mPreviousViews.clear();
        mPreviousViews.clear();
        int newWindowStartUnbounded = childIndex - mActiveOffset;
        int newWindowStartUnbounded = childIndex - mActiveOffset;
        int newWindowEndUnbounded = newWindowStartUnbounded + mNumActiveViews - 1;
        int newWindowEndUnbounded = newWindowStartUnbounded + getNumActiveViews() - 1;
        int newWindowStart = Math.max(0, newWindowStartUnbounded);
        int newWindowStart = Math.max(0, newWindowStartUnbounded);
        int newWindowEnd = Math.min(adapterCount - 1, newWindowEndUnbounded);
        int newWindowEnd = Math.min(adapterCount - 1, newWindowEndUnbounded);


@@ -420,8 +437,8 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
            newWindowStart = newWindowStartUnbounded;
            newWindowStart = newWindowStartUnbounded;
            newWindowEnd = newWindowEndUnbounded;
            newWindowEnd = newWindowEndUnbounded;
        }
        }
        int rangeStart = modulo(newWindowStart, adapterCount);
        int rangeStart = modulo(newWindowStart, getWindowSize());
        int rangeEnd = modulo(newWindowEnd, adapterCount);
        int rangeEnd = modulo(newWindowEnd, getWindowSize());


        boolean wrap = false;
        boolean wrap = false;
        if (rangeStart > rangeEnd) {
        if (rangeStart > rangeEnd) {
@@ -450,11 +467,12 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
        }
        }


        // If the window has changed
        // 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
            // Run through the indices in the new range
            for (int i = newWindowStart; i <= newWindowEnd; i++) {
            for (int i = newWindowStart; i <= newWindowEnd; i++) {


                int index = modulo(i, adapterCount);
                int index = modulo(i, getWindowSize());
                int oldRelativeIndex;
                int oldRelativeIndex;
                if (mViewsMap.containsKey(index)) {
                if (mViewsMap.containsKey(index)) {
                    oldRelativeIndex = mViewsMap.get(index).index;
                    oldRelativeIndex = mViewsMap.get(index).index;
@@ -494,13 +512,6 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
                }
                }
                mViewsMap.get(index).view.bringToFront();
                mViewsMap.get(index).view.bringToFront();
            }
            }

            for (int i = 0; i < mViewsToBringToFront.size(); i++) {
                View v = mViewsToBringToFront.get(i);
                v.bringToFront();
            }
            mViewsToBringToFront.clear();

            mCurrentWindowStart = newWindowStart;
            mCurrentWindowStart = newWindowStart;
            mCurrentWindowEnd = newWindowEnd;
            mCurrentWindowEnd = newWindowEnd;
            mCurrentWindowStartUnbounded = newWindowStartUnbounded;
            mCurrentWindowStartUnbounded = newWindowStartUnbounded;
+36 −28
Original line number Original line Diff line number Diff line
@@ -129,7 +129,7 @@ public class StackView extends AdapterViewAnimator {
    }
    }


    private void initStackView() {
    private void initStackView() {
        configureViewAnimator(NUM_ACTIVE_VIEWS, NUM_ACTIVE_VIEWS - 2);
        configureViewAnimator(NUM_ACTIVE_VIEWS, 1);
        setStaticTransformationsEnabled(true);
        setStaticTransformationsEnabled(true);
        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        mTouchSlop = configuration.getScaledTouchSlop();
        mTouchSlop = configuration.getScaledTouchSlop();
@@ -165,7 +165,7 @@ public class StackView extends AdapterViewAnimator {
     * Animate the views between different relative indexes within the {@link AdapterViewAnimator}
     * Animate the views between different relative indexes within the {@link AdapterViewAnimator}
     */
     */
    void animateViewForTransition(int fromIndex, int toIndex, View view) {
    void animateViewForTransition(int fromIndex, int toIndex, View view) {
        if (fromIndex == -1 && toIndex == 0) {
        if (fromIndex == -1 && toIndex != 0) {
            // Fade item in
            // Fade item in
            if (view.getAlpha() == 1) {
            if (view.getAlpha() == 1) {
                view.setAlpha(0);
                view.setAlpha(0);
@@ -175,7 +175,7 @@ public class StackView extends AdapterViewAnimator {
            ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f);
            ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f);
            fadeIn.setDuration(DEFAULT_ANIMATION_DURATION);
            fadeIn.setDuration(DEFAULT_ANIMATION_DURATION);
            fadeIn.start();
            fadeIn.start();
        } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
        } else if (fromIndex == 0 && toIndex == 1) {
            // Slide item in
            // Slide item in
            view.setVisibility(VISIBLE);
            view.setVisibility(VISIBLE);


@@ -189,7 +189,7 @@ public class StackView extends AdapterViewAnimator {
            pa.setDuration(duration);
            pa.setDuration(duration);
            pa.setInterpolator(new LinearInterpolator());
            pa.setInterpolator(new LinearInterpolator());
            pa.start();
            pa.start();
        } else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) {
        } else if (fromIndex == 1 && toIndex == 0) {
            // Slide item out
            // Slide item out
            int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity));
            int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity));


@@ -201,7 +201,7 @@ public class StackView extends AdapterViewAnimator {
            pa.setDuration(duration);
            pa.setDuration(duration);
            pa.setInterpolator(new LinearInterpolator());
            pa.setInterpolator(new LinearInterpolator());
            pa.start();
            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
            // Make sure this view that is "waiting in the wings" is invisible
            view.setAlpha(0.0f);
            view.setAlpha(0.0f);
            view.setVisibility(INVISIBLE);
            view.setVisibility(INVISIBLE);
@@ -223,9 +223,10 @@ public class StackView extends AdapterViewAnimator {
    private void transformViewAtIndex(int index, View view) {
    private void transformViewAtIndex(int index, View view) {
        float maxPerpectiveShift = mMeasuredHeight * PERSPECTIVE_SHIFT_FACTOR;
        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);
        float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scale);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scale);
@@ -245,8 +246,20 @@ public class StackView extends AdapterViewAnimator {
        pa.start();
        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() {
    private void updateChildTransforms() {
        for (int i = 0; i < mNumActiveViews - 1; i++) {
        for (int i = 0; i < getNumActiveViews(); i++) {
            View v = getViewAtRelativeIndex(i);
            View v = getViewAtRelativeIndex(i);
            if (v != null) {
            if (v != null) {
                transformViewAtIndex(i, v);
                transformViewAtIndex(i, v);
@@ -341,19 +354,17 @@ public class StackView extends AdapterViewAnimator {


            int activeIndex;
            int activeIndex;
            if (mStackMode == ITEMS_SLIDE_UP) {
            if (mStackMode == ITEMS_SLIDE_UP) {
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ?
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1;
                        mNumActiveViews - 1 : mNumActiveViews - 2;
            } else {
            } else {
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ?
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0;
                        mNumActiveViews - 2 : mNumActiveViews - 1;
            }
            }


            if (mLoopViews) {
            if (mLoopViews) {
                mStackSlider.setMode(StackSlider.NORMAL_MODE);
                mStackSlider.setMode(StackSlider.NORMAL_MODE);
            } else if (mCurrentWindowStartUnbounded + activeIndex == 0) {
            } else if (mCurrentWindowStartUnbounded + activeIndex == -1) {
                activeIndex++;
                mStackSlider.setMode(StackSlider.BEGINNING_OF_STACK_MODE);
                mStackSlider.setMode(StackSlider.BEGINNING_OF_STACK_MODE);
            } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount()) {
            } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) {
                activeIndex--;
                mStackSlider.setMode(StackSlider.END_OF_STACK_MODE);
                mStackSlider.setMode(StackSlider.END_OF_STACK_MODE);
            } else {
            } else {
                mStackSlider.setMode(StackSlider.NORMAL_MODE);
                mStackSlider.setMode(StackSlider.NORMAL_MODE);
@@ -439,8 +450,7 @@ public class StackView extends AdapterViewAnimator {
        final int pointerId = ev.getPointerId(activePointerIndex);
        final int pointerId = ev.getPointerId(activePointerIndex);
        if (pointerId == mActivePointerId) {
        if (pointerId == mActivePointerId) {


            int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? mNumActiveViews - 1
            int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1;
                    : mNumActiveViews - 2;


            View v = getViewAtRelativeIndex(activeViewIndex);
            View v = getViewAtRelativeIndex(activeViewIndex);
            if (v == null) return;
            if (v == null) return;
@@ -498,18 +508,18 @@ public class StackView extends AdapterViewAnimator {
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
            // Swipe threshold exceeded, swipe down
            // Swipe threshold exceeded, swipe down
            if (mStackMode == ITEMS_SLIDE_UP) {
            if (mStackMode == ITEMS_SLIDE_UP) {
                showNext();
            } else {
                showPrevious();
                showPrevious();
            } else {
                showNext();
            }
            }
            mHighlight.bringToFront();
            mHighlight.bringToFront();
        } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
        } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
            // Swipe threshold exceeded, swipe up
            // Swipe threshold exceeded, swipe up
            if (mStackMode == ITEMS_SLIDE_UP) {
            if (mStackMode == ITEMS_SLIDE_UP) {
                showPrevious();
            } else {
                showNext();
                showNext();
            } else {
                showPrevious();
            }
            }


            mHighlight.bringToFront();
            mHighlight.bringToFront();
@@ -643,13 +653,13 @@ public class StackView extends AdapterViewAnimator {
                    mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    break;
                    break;
                case BEGINNING_OF_STACK_MODE:
                case END_OF_STACK_MODE:
                    r = r * 0.2f;
                    r = r * 0.2f;
                    viewLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    viewLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    mHighlight.setAlpha(highlightAlphaInterpolator(r));
                    mHighlight.setAlpha(highlightAlphaInterpolator(r));
                    break;
                    break;
                case END_OF_STACK_MODE:
                case BEGINNING_OF_STACK_MODE:
                    r = (1-r) * 0.2f;
                    r = (1-r) * 0.2f;
                    viewLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
                    viewLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
@@ -735,13 +745,11 @@ public class StackView extends AdapterViewAnimator {
    public void onRemoteAdapterConnected() {
    public void onRemoteAdapterConnected() {
        super.onRemoteAdapterConnected();
        super.onRemoteAdapterConnected();
        // On first run, we want to set the stack to the end.
        // On first run, we want to set the stack to the end.
        if (mAdapter != null && mWhichChild == -1) {
        if (mWhichChild == -1) {
            mWhichChild = mAdapter.getCount() - 1;
            mWhichChild = 0;
        }
        }
        if (mWhichChild >= 0) {
        setDisplayedChild(mWhichChild);
        setDisplayedChild(mWhichChild);
    }
    }
    }


    LayoutParams createOrReuseLayoutParams(View v) {
    LayoutParams createOrReuseLayoutParams(View v) {
        final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
        final ViewGroup.LayoutParams currentLp = v.getLayoutParams();