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

Commit 70009e42 authored by Adam Cohen's avatar Adam Cohen
Browse files

Making the reordering play nice with the 3D widget carousel

-> Ensuring that transforms, hidden side pages, alphas all transition
   and fade seamlessly to and from the carousel

Change-Id: I6197f17899135a9e551ff1691c63ad5a2bb1d0f7
parent 33384ed6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ public class KeyguardHostView extends KeyguardViewBase {

        addDefaultWidgets();
        addWidgetsFromSettings();
        mSwitchPageRunnable.run();

        mViewStateManager = new KeyguardViewStateManager();
        SlidingChallengeLayout slider =
@@ -217,7 +218,6 @@ public class KeyguardHostView extends KeyguardViewBase {
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mAppWidgetHost.startListening();
        post(mSwitchPageRunnable);
    }

    @Override
+8 −0
Original line number Diff line number Diff line
@@ -86,6 +86,14 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
        mChallengeLayout.showBouncer();
    }

    public void fadeOutSecurity(int duration) {
        ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
    }

    public void fadeInSecurity(int duration) {
        ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration);
    }

    public void onPageSwitch(View newPage, int newPageIndex) {
        // Reset the previous page size and ensure the current page is sized appropriately.
        // We only modify the page state if it is not currently under control by the slider.
+153 −7
Original line number Diff line number Diff line
@@ -15,9 +15,19 @@
 */
package com.android.internal.policy.impl.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import java.util.ArrayList;

import com.android.internal.R;

@@ -26,6 +36,8 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
    private float mAdjacentPagesAngle;
    private static float MAX_SCROLL_PROGRESS = 1.3f;
    private static float CAMERA_DISTANCE = 10000;
    protected AnimatorSet mChildrenTransformsAnimator;
    float[] mTmpTransform = new float[3];

    public KeyguardWidgetCarousel(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
@@ -48,13 +60,15 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
        View child = getChildAt(index);
        if (child == null) return 0f;

        float maxAlpha = KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER;

        float scrollProgress = getScrollProgress(screenCenter, child, index);
        if (!isOverScrollChild(index, scrollProgress)) {
            scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
            float alpha = 1 - Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
            float alpha = maxAlpha - maxAlpha * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
            return alpha;
        } else {
            return 1f;
            return maxAlpha;
        }
    }

@@ -73,16 +87,17 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
                }
            }
        }

    }

    @Override
    protected void screenScrolled(int screenCenter) {
        mScreenCenter = screenCenter;
        updatePageAlphaValues(screenCenter);
        if (isReordering(false)) return;
        for (int i = 0; i < getChildCount(); i++) {
            KeyguardWidgetFrame v = getWidgetPageAt(i);
            float scrollProgress = getScrollProgress(screenCenter, v, i);
            float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
            if (v == mDragView || v == null) continue;
            v.setCameraDistance(CAMERA_DISTANCE);

@@ -90,17 +105,15 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
                v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
                v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
            } else {
                scrollProgress = getBoundedScrollProgress(screenCenter, v, i);
                int width = v.getMeasuredWidth();
                float pivotX = (width / 2f) + scrollProgress * (width / 2f);
                float pivotX = (width / 2f) + boundedProgress * (width / 2f);
                float pivotY = v.getMeasuredHeight() / 2;
                float rotationY = - mAdjacentPagesAngle * scrollProgress;
                float rotationY = - mAdjacentPagesAngle * boundedProgress;
                v.setPivotX(pivotX);
                v.setPivotY(pivotY);
                v.setRotationY(rotationY);
                v.setOverScrollAmount(0f, false);
            }

            float alpha = v.getAlpha();
            // If the view has 0 alpha, we set it to be invisible so as to prevent
            // it from accepting touches
@@ -111,4 +124,137 @@ public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
            }
        }
    }

    void animatePagesToNeutral() {
        if (mChildrenTransformsAnimator != null) {
            mChildrenTransformsAnimator.cancel();
            mChildrenTransformsAnimator = null;
        }

        int count = getChildCount();
        PropertyValuesHolder alpha;
        PropertyValuesHolder outlineAlpha;
        PropertyValuesHolder rotationY;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        for (int i = 0; i < count; i++) {
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
            if (!inVisibleRange) {
                child.setRotationY(0f);
            }
            alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", 1.0f);
            rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
            child.setVisibility(VISIBLE);
            if (!inVisibleRange) {
                a.setInterpolator(mSlowFadeInterpolator);
            }
            anims.add(a);
        }

        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
        mChildrenTransformsAnimator = new AnimatorSet();
        mChildrenTransformsAnimator.playTogether(anims);

        mChildrenTransformsAnimator.setDuration(duration);
        mChildrenTransformsAnimator.start();
    }

    private void getTransformForPage(int screenCenter, int index, float[] transform) {
        View child = getChildAt(index);
        float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
        float rotationY = - mAdjacentPagesAngle * boundedProgress;
        int width = child.getMeasuredWidth();
        float pivotX = (width / 2f) + boundedProgress * (width / 2f);
        float pivotY = child.getMeasuredHeight() / 2;

        transform[0] = pivotX;
        transform[1] = pivotY;
        transform[2] = rotationY;
    }

    Interpolator mFastFadeInterpolator = new Interpolator() {
        Interpolator mInternal = new DecelerateInterpolator(1.5f);
        float mFactor = 2.5f;
        @Override
        public float getInterpolation(float input) {
            return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
        }
    };

    Interpolator mSlowFadeInterpolator = new Interpolator() {
        Interpolator mInternal = new AccelerateInterpolator(1.5f);
        float mFactor = 1.3f;
        @Override
        public float getInterpolation(float input) {
            input -= (1 - 1 / mFactor);
            input = mFactor * Math.max(input, 0f);
            return mInternal.getInterpolation(input);
        }
    };

    void animatePagesToCarousel() {
        if (mChildrenTransformsAnimator != null) {
            mChildrenTransformsAnimator.cancel();
            mChildrenTransformsAnimator = null;
        }

        int count = getChildCount();
        PropertyValuesHolder alpha;
        PropertyValuesHolder outlineAlpha;
        PropertyValuesHolder rotationY;
        PropertyValuesHolder pivotX;
        PropertyValuesHolder pivotY;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        for (int i = 0; i < count; i++) {
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            float finalAlpha = getAlphaForPage(mScreenCenter, i);
            getTransformForPage(mScreenCenter, i, mTmpTransform);

            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);

            ObjectAnimator a;
            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalAlpha);
            pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
            pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
            rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);

            if (inVisibleRange) {
                // for the central pages we animate into a rotated state
                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
                        pivotX, pivotY, rotationY);
            } else {
                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
                a.setInterpolator(mFastFadeInterpolator);
            }
            anims.add(a);
        }

        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
        mChildrenTransformsAnimator = new AnimatorSet();
        mChildrenTransformsAnimator.playTogether(anims);

        mChildrenTransformsAnimator.setDuration(duration);
        mChildrenTransformsAnimator.start();
    }

    protected void reorderStarting() {
        mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
        animatePagesToNeutral();
    }

    protected boolean zoomIn(final Runnable onCompleteRunnable) {
        animatePagesToCarousel();
        return super.zoomIn(onCompleteRunnable);
    }

    @Override
    protected void onEndReordering() {
        super.onEndReordering();
        mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
    }
}
+37 −14
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
    protected static float OVERSCROLL_MAX_ROTATION = 30;
    private static final boolean PERFORM_OVERSCROLL_ROTATION = true;

    private KeyguardViewStateManager mViewStateManager;
    protected KeyguardViewStateManager mViewStateManager;
    private LockPatternUtils mLockPatternUtils;

    // Related to the fading in / out background outlines
@@ -59,7 +59,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
    protected int mScreenCenter;
    private boolean mHasLayout = false;
    private boolean mHasMeasure = false;
    private boolean mShowHintsOnLayout = false;
    boolean showHintsAfterLayout = false;

    private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;

@@ -291,7 +291,9 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
        if (mViewStateManager != null) {
            mViewStateManager.onPageBeginMoving();
        }
        if (!isReordering(false)) {
            showOutlinesAndSidePages();
        }
        userActivity();
    }

@@ -300,17 +302,22 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
        if (mViewStateManager != null) {
            mViewStateManager.onPageEndMoving();
        }

        // In the reordering case, the pages will be faded appropriately on completion
        // of the zoom in animation.
        if (!isReordering(false)) {
            hideOutlinesAndSidePages();
        }
    }

    private void enablePageLayers() {
    protected void enablePageLayers() {
        int children = getChildCount();
        for (int i = 0; i < children; i++) {
            getWidgetPageAt(i).enableHardwareLayersForContent();
        }
    }

    private void disablePageLayers() {
    protected void disablePageLayers() {
        int children = getChildCount();
        for (int i = 0; i < children; i++) {
            getWidgetPageAt(i).disableHardwareLayersForContent();
@@ -440,10 +447,15 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
        return mCameraWidgetEnabled;
    }

    protected void reorderStarting() {
        showOutlinesAndSidePages();
    }

    @Override
    protected void onStartReordering() {
        super.onStartReordering();
        showOutlinesAndSidePages();
        enablePageLayers();
        reorderStarting();
    }

    @Override
@@ -453,7 +465,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
    }

    void showOutlinesAndSidePages() {
        enablePageLayers();
        animateOutlinesAndSidePages(true);
    }

@@ -466,7 +477,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
            showOutlinesAndSidePages();
        } else {
            // The layout hints depend on layout being run once
            mShowHintsOnLayout = true;
            showHintsAfterLayout = true;
        }
    }

@@ -477,16 +488,17 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
        mHasLayout = false;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (mShowHintsOnLayout) {
        if (showHintsAfterLayout) {
            post(new Runnable() {
                @Override
                public void run() {
                    showOutlinesAndSidePages();
                }
            });
            mShowHintsOnLayout = false;
            showHintsAfterLayout = false;
        }
        mHasLayout = true;
    }
@@ -523,17 +535,22 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
    }

    void animateOutlinesAndSidePages(final boolean show) {
        animateOutlinesAndSidePages(show, -1);
    }

    void animateOutlinesAndSidePages(final boolean show, int duration) {
        if (mChildrenOutlineFadeAnimation != null) {
            mChildrenOutlineFadeAnimation.cancel();
            mChildrenOutlineFadeAnimation = null;
        }

        int count = getChildCount();
        PropertyValuesHolder alpha;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        int duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
        if (duration == -1) {
            duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
                CHILDREN_OUTLINE_FADE_OUT_DURATION;
        }

        int curPage = getNextPage();
        for (int i = 0; i < count; i++) {
@@ -559,6 +576,12 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit

        mChildrenOutlineFadeAnimation.setDuration(duration);
        mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (show) {
                    enablePageLayers();
                }
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                if (!show) {
+2 −2
Original line number Diff line number Diff line
@@ -1995,7 +1995,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
    }

    // "Zooms out" the PagedView to reveal more side pages
    boolean zoomOut() {
    protected boolean zoomOut() {
        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
            mZoomInOutAnim.cancel();
        }
@@ -2097,7 +2097,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
    }

    // "Zooms in" the PagedView to highlight the current page
    boolean zoomIn(final Runnable onCompleteRunnable) {
    protected boolean zoomIn(final Runnable onCompleteRunnable) {
        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
            mZoomInOutAnim.cancel();
        }