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

Commit 98f8530a authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Animations for Keyguard user switcher.

Bug: 15757197
Change-Id: Ia3fcc0f771cea37fc2d57181d859373c423954a7
parent 546c635a
Loading
Loading
Loading
Loading
+61 −12
Original line number Diff line number Diff line
@@ -26,38 +26,70 @@ import android.view.animation.Interpolator;
 */
public class AppearAnimationUtils implements AppearAnimationCreator<View> {

    public static final long APPEAR_DURATION = 220;
    public static final long DEFAULT_APPEAR_DURATION = 220;

    private final Interpolator mLinearOutSlowIn;
    private final Interpolator mInterpolator;
    private final float mStartTranslation;
    private final AppearAnimationProperties mProperties = new AppearAnimationProperties();
    private final float mDelayScale;
    private final long mDuration;

    public AppearAnimationUtils(Context ctx) {
        this(ctx, 1.0f, 1.0f);
        this(ctx, DEFAULT_APPEAR_DURATION,
                ctx.getResources().getDimensionPixelSize(R.dimen.appear_y_translation_start),
                1.0f,
                AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in));
    }

    public AppearAnimationUtils(Context ctx, float delayScaleFactor,
            float translationScaleFactor) {
        mLinearOutSlowIn = AnimationUtils.loadInterpolator(
                ctx, android.R.interpolator.linear_out_slow_in);
    public AppearAnimationUtils(Context ctx, long duration, float translationScaleFactor,
            float delayScaleFactor, Interpolator interpolator) {
        mInterpolator = interpolator;
        mStartTranslation = ctx.getResources().getDimensionPixelOffset(
                R.dimen.appear_y_translation_start) * translationScaleFactor;
        mDelayScale = delayScaleFactor;
        mDuration = duration;
    }

    public void startAppearAnimation(View[][] objects, final Runnable finishListener) {
        startAppearAnimation(objects, finishListener, this);
    }

    public void startAppearAnimation(View[] objects, final Runnable finishListener) {
        startAppearAnimation(objects, finishListener, this);
    }

    public <T> void startAppearAnimation(T[][] objects, final Runnable finishListener,
            AppearAnimationCreator<T> creator) {
        AppearAnimationProperties properties = getDelays(objects);
        startAnimations(properties, objects, finishListener, creator);
    }

    public <T> void startAppearAnimation(T[] objects, final Runnable finishListener,
            AppearAnimationCreator<T> creator) {
        AppearAnimationProperties properties = getDelays(objects);
        startAnimations(properties, objects, finishListener, creator);
    }

    private <T> void startAnimations(AppearAnimationProperties properties, T[] objects,
            final Runnable finishListener, AppearAnimationCreator<T> creator) {
        if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
            finishListener.run();
            return;
        }
        for (int row = 0; row < properties.delays.length; row++) {
            long[] columns = properties.delays[row];
            long delay = columns[0];
            Runnable endRunnable = null;
            if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == 0) {
                endRunnable = finishListener;
            }
            creator.createAnimation(objects[row], delay, mDuration,
                    mStartTranslation, mInterpolator, endRunnable);
        }
    }

    private <T> void startAnimations(AppearAnimationProperties properties, T[][] objects,
            final Runnable finishListener, AppearAnimationCreator creator) {;
            final Runnable finishListener, AppearAnimationCreator<T> creator) {
        if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
            finishListener.run();
            return;
@@ -70,15 +102,32 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
                if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == col) {
                    endRunnable = finishListener;
                }
                creator.createAnimation(objects[row][col], delay, APPEAR_DURATION,
                        mStartTranslation, mLinearOutSlowIn, endRunnable);
                creator.createAnimation(objects[row][col], delay, mDuration,
                        mStartTranslation, mInterpolator, endRunnable);
            }
        }
    }

    private <T> AppearAnimationProperties getDelays(T[] items) {
        long maxDelay = -1;
        mProperties.maxDelayColIndex = -1;
        mProperties.maxDelayRowIndex = -1;
        mProperties.delays = new long[items.length][];
        for (int row = 0; row < items.length; row++) {
            mProperties.delays[row] = new long[1];
            long delay = calculateDelay(row, 0);
            mProperties.delays[row][0] = delay;
            if (items[row] != null && delay > maxDelay) {
                maxDelay = delay;
                mProperties.maxDelayColIndex = 0;
                mProperties.maxDelayRowIndex = row;
            }
        }
        return mProperties;
    }

    private <T> AppearAnimationProperties getDelays(T[][] items) {
        long maxDelay = 0;
        long maxDelay = -1;
        mProperties.maxDelayColIndex = -1;
        mProperties.maxDelayRowIndex = -1;
        mProperties.delays = new long[items.length][];
@@ -103,7 +152,7 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
    }

    public Interpolator getInterpolator() {
        return mLinearOutSlowIn;
        return mInterpolator;
    }

    public float getStartTranslation() {
+6 −3
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.LinearLayout;
@@ -108,8 +109,10 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
    public KeyguardPatternView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
        mAppearAnimationUtils = new AppearAnimationUtils(context, 1.5f /* delayScale */,
                2.0f /* transitionScale */);
        mAppearAnimationUtils = new AppearAnimationUtils(context,
                AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* delayScale */,
                2.0f /* transitionScale */, AnimationUtils.loadInterpolator(
                        mContext, android.R.interpolator.linear_out_slow_in));
    }

    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
@@ -420,7 +423,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
                this);
        if (!TextUtils.isEmpty(mHelpMessage.getText())) {
            mAppearAnimationUtils.createAnimation(mHelpMessage, 0,
                    AppearAnimationUtils.APPEAR_DURATION,
                    AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
                    mAppearAnimationUtils.getStartTranslation(),
                    mAppearAnimationUtils.getInterpolator(),
                    null /* finishRunnable */);
+3 −2
Original line number Diff line number Diff line
@@ -14,7 +14,8 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.android.systemui.statusbar.AlphaOptimizedLinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/keyguard_user_switcher"
        android:orientation="vertical"
        android:layout_height="wrap_content"
@@ -22,4 +23,4 @@
        android:gravity="end"
        android:visibility="gone"
        android:paddingTop="4dp">
</LinearLayout>
</com.android.systemui.statusbar.AlphaOptimizedLinearLayout>
+5 −0
Original line number Diff line number Diff line
@@ -116,4 +116,9 @@ public class UserDetailItemView extends LinearLayout {
        boolean activated = ArrayUtils.contains(getDrawableState(), android.R.attr.state_activated);
        mName.setTypeface(activated ? mActivatedTypeface : mRegularTypeface);
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }
}
+75 −2
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.systemui.statusbar.phone;

import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -48,6 +52,7 @@ public class KeyguardStatusBarView extends RelativeLayout
    private KeyguardUserSwitcher mKeyguardUserSwitcher;

    private int mSystemIconsSwitcherHiddenExpandedMargin;
    private Interpolator mFastOutSlowInInterpolator;

    public KeyguardStatusBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -61,6 +66,8 @@ public class KeyguardStatusBarView extends RelativeLayout
        mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
        mBatteryLevel = (TextView) findViewById(R.id.battery_level);
        loadDimens();
        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                android.R.interpolator.fast_out_slow_in);
        updateUserSwitcher();
    }

@@ -70,7 +77,14 @@ public class KeyguardStatusBarView extends RelativeLayout
    }

    private void updateVisibilities() {
        mMultiUserSwitch.setVisibility(!mKeyguardUserSwitcherShowing ? VISIBLE : GONE);
        if (mMultiUserSwitch.getParent() != this && !mKeyguardUserSwitcherShowing) {
            if (mMultiUserSwitch.getParent() != null) {
                getOverlay().remove(mMultiUserSwitch);
            }
            addView(mMultiUserSwitch, 0);
        } else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) {
            removeView(mMultiUserSwitch);
        }
        mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE);
    }

@@ -137,12 +151,71 @@ public class KeyguardStatusBarView extends RelativeLayout
        updateUserSwitcher();
    }

    public void setKeyguardUserSwitcherShowing(boolean showing) {
    public void setKeyguardUserSwitcherShowing(boolean showing, boolean animate) {
        mKeyguardUserSwitcherShowing = showing;
        if (animate) {
            animateNextLayoutChange();
        }
        updateVisibilities();
        updateSystemIconsLayoutParams();
    }

    private void animateNextLayoutChange() {
        final int systemIconsCurrentX = mSystemIconsSuperContainer.getLeft();
        final boolean userSwitcherVisible = mMultiUserSwitch.getParent() == this;
        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                getViewTreeObserver().removeOnPreDrawListener(this);
                boolean userSwitcherHiding = userSwitcherVisible
                        && mMultiUserSwitch.getParent() != KeyguardStatusBarView.this;
                mSystemIconsSuperContainer.setX(systemIconsCurrentX);
                mSystemIconsSuperContainer.animate()
                        .translationX(0)
                        .setDuration(400)
                        .setStartDelay(userSwitcherHiding ? 300 : 0)
                        .setInterpolator(mFastOutSlowInInterpolator)
                        .start();
                if (userSwitcherHiding) {
                    getOverlay().add(mMultiUserSwitch);
                    mMultiUserSwitch.animate()
                            .alpha(0f)
                            .setDuration(300)
                            .setStartDelay(0)
                            .setInterpolator(PhoneStatusBar.ALPHA_OUT)
                            .withEndAction(new Runnable() {
                                @Override
                                public void run() {
                                    mMultiUserSwitch.setAlpha(1f);
                                    getOverlay().remove(mMultiUserSwitch);
                                }
                            })
                            .start();

                } else {
                    mMultiUserSwitch.setAlpha(0f);
                    mMultiUserSwitch.animate()
                            .alpha(1f)
                            .setDuration(300)
                            .setStartDelay(200)
                            .setInterpolator(PhoneStatusBar.ALPHA_IN);
                }
                return true;
            }
        });

    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (visibility != View.VISIBLE) {
            mSystemIconsSuperContainer.animate().cancel();
            mMultiUserSwitch.animate().cancel();
            mMultiUserSwitch.setAlpha(1f);
        }
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
Loading