diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index eb0a7258c7331..3994fbdca2df1 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -80,6 +80,8 @@ public class LockPatternView extends View { private static final int LINE_FADE_OUT_DURATION_MILLIS = 500; private static final int LINE_FADE_OUT_DELAY_MILLIS = 150; private static final int DOT_ACTIVATION_DURATION_MILLIS = 50; + private static final int DOT_RADIUS_INCREASE_DURATION_MILLIS = 96; + private static final int DOT_RADIUS_DECREASE_DURATION_MILLIS = 192; private final CellState[][] mCellStates; private final int mDotSize; @@ -245,9 +247,7 @@ public class LockPatternView extends View { public float lineEndX = Float.MIN_VALUE; public float lineEndY = Float.MIN_VALUE; @Nullable - ValueAnimator lineEndAnimator; - @Nullable - ValueAnimator lineDisappearingAnimator; + Animator activationAnimator; } /** @@ -804,33 +804,39 @@ public class LockPatternView extends View { private void startCellActivatedAnimation(Cell cell) { final CellState cellState = mCellStates[cell.row][cell.column]; - if (mDotSize != mDotSizeActivated) { - startRadiusAnimation(mDotSize / 2, mDotSizeActivated / 2, 96, - mLinearOutSlowInInterpolator, - cellState, new Runnable() { - @Override - public void run() { - startRadiusAnimation(mDotSizeActivated / 2, mDotSize / 2, 192, - mFastOutSlowInInterpolator, - cellState, null); - } - }); + + if (cellState.activationAnimator != null) { + cellState.activationAnimator.cancel(); } - startDotActivationColorAnimation(cellState); - startLineEndAnimation(cellState, mInProgressX, mInProgressY, - getCenterXForColumn(cell.column), getCenterYForRow(cell.row)); - startLineDisappearingAnimation(cellState); + AnimatorSet animatorSet = new AnimatorSet(); + AnimatorSet.Builder animatorSetBuilder = animatorSet + .play(createLineDisappearingAnimation()) + .with(createLineEndAnimation(cellState, mInProgressX, mInProgressY, + getCenterXForColumn(cell.column), getCenterYForRow(cell.row))); + if (mDotSize != mDotSizeActivated) { + animatorSetBuilder.with(createDotRadiusAnimation(cellState)); + } + if (mDotColor != mDotActivatedColor) { + animatorSetBuilder.with(createDotActivationColorAnimation(cellState)); + } + + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + cellState.activationAnimator = null; + invalidate(); + } + }); + cellState.activationAnimator = animatorSet; + animatorSet.start(); } - private void startDotActivationColorAnimation(CellState cellState) { + private Animator createDotActivationColorAnimation(CellState cellState) { ValueAnimator.AnimatorUpdateListener updateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - cellState.activationAnimationProgress = - (float) valueAnimator.getAnimatedValue(); - invalidate(); - } + valueAnimator -> { + cellState.activationAnimationProgress = + (float) valueAnimator.getAnimatedValue(); + invalidate(); }; ValueAnimator activateAnimator = ValueAnimator.ofFloat(0f, 1f); ValueAnimator deactivateAnimator = ValueAnimator.ofFloat(1f, 0f); @@ -847,82 +853,62 @@ public class LockPatternView extends View { .after(LINE_FADE_OUT_DELAY_MILLIS + LINE_FADE_OUT_DURATION_MILLIS - DOT_ACTIVATION_DURATION_MILLIS * 2) .after(activateAnimator); - set.start(); + return set; } /** * On the last frame before cell activates the end point of in progress line is not aligned * with dot center so we execute a short animation moving the end point to exact dot center. */ - private void startLineEndAnimation(final CellState state, + private Animator createLineEndAnimation(final CellState state, final float startX, final float startY, final float targetX, final float targetY) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); - valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float t = (float) animation.getAnimatedValue(); - state.lineEndX = (1 - t) * startX + t * targetX; - state.lineEndY = (1 - t) * startY + t * targetY; - invalidate(); - } - }); - valueAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - state.lineEndAnimator = null; - } + valueAnimator.addUpdateListener(animation -> { + float t = (float) animation.getAnimatedValue(); + state.lineEndX = (1 - t) * startX + t * targetX; + state.lineEndY = (1 - t) * startY + t * targetY; + invalidate(); }); valueAnimator.setInterpolator(mFastOutSlowInInterpolator); valueAnimator.setDuration(LINE_END_ANIMATION_DURATION_MILLIS); - valueAnimator.start(); - state.lineEndAnimator = valueAnimator; + return valueAnimator; } /** * Starts animator to fade out a line segment. It does only invalidate because all the * transitions are applied in {@code onDraw} method. */ - private void startLineDisappearingAnimation(final CellState state) { + private Animator createLineDisappearingAnimation() { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); - valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - invalidate(); - } - }); - valueAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - state.lineDisappearingAnimator = null; - } - }); + valueAnimator.addUpdateListener(animation -> invalidate()); valueAnimator.setStartDelay(LINE_FADE_OUT_DELAY_MILLIS); valueAnimator.setDuration(LINE_FADE_OUT_DURATION_MILLIS); - valueAnimator.start(); - state.lineDisappearingAnimator = valueAnimator; + return valueAnimator; } - private void startRadiusAnimation(float start, float end, long duration, - Interpolator interpolator, final CellState state, final Runnable endRunnable) { - ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, end); - valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - state.radius = (float) animation.getAnimatedValue(); - invalidate(); - } - }); - if (endRunnable != null) { - valueAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - endRunnable.run(); - } - }); - } - valueAnimator.setInterpolator(interpolator); - valueAnimator.setDuration(duration); - valueAnimator.start(); + private Animator createDotRadiusAnimation(CellState state) { + float defaultRadius = mDotSize / 2f; + float activatedRadius = mDotSizeActivated / 2f; + + ValueAnimator.AnimatorUpdateListener animatorUpdateListener = + animation -> { + state.radius = (float) animation.getAnimatedValue(); + invalidate(); + }; + + ValueAnimator activationAnimator = ValueAnimator.ofFloat(defaultRadius, activatedRadius); + activationAnimator.addUpdateListener(animatorUpdateListener); + activationAnimator.setInterpolator(mLinearOutSlowInInterpolator); + activationAnimator.setDuration(DOT_RADIUS_INCREASE_DURATION_MILLIS); + + ValueAnimator deactivationAnimator = ValueAnimator.ofFloat(activatedRadius, defaultRadius); + deactivationAnimator.addUpdateListener(animatorUpdateListener); + deactivationAnimator.setInterpolator(mFastOutSlowInInterpolator); + deactivationAnimator.setDuration(DOT_RADIUS_DECREASE_DURATION_MILLIS); + + AnimatorSet set = new AnimatorSet(); + set.playSequentially(activationAnimator, deactivationAnimator); + return set; } // helper method to find which cell a point maps to @@ -1136,16 +1122,14 @@ public class LockPatternView extends View { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { CellState state = mCellStates[i][j]; - if (state.lineEndAnimator != null) { - state.lineEndAnimator.cancel(); - state.lineEndAnimator = null; + if (state.activationAnimator != null) { + state.activationAnimator.cancel(); + state.activationAnimator = null; + state.radius = mDotSize / 2f; + state.activationAnimationProgress = 0f; state.lineEndX = Float.MIN_VALUE; state.lineEndY = Float.MIN_VALUE; } - if (state.lineDisappearingAnimator != null) { - state.lineDisappearingAnimator.cancel(); - state.lineDisappearingAnimator = null; - } } } }