LockPatternView dot activation animation.
Animate dot color when it's activated, duration is synchronized with line disappearing animation. Do not animate dot size if it's not needed. Bug: 196067470 Bug: 193417780 Tests: Manually Change-Id: I13fa478f434b2c56a5818a4b639f3e38f7c05c4d (cherry picked from commit 450633259bc6283f25d98d5e056d39e74bcb8cc7)
This commit is contained in:
@@ -18,6 +18,7 @@ package com.android.internal.widget;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
@@ -56,6 +57,7 @@ import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.graphics.ColorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -77,6 +79,7 @@ public class LockPatternView extends View {
|
||||
private static final int LINE_END_ANIMATION_DURATION_MILLIS = 50;
|
||||
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 final CellState[][] mCellStates;
|
||||
|
||||
private final int mDotSize;
|
||||
@@ -156,6 +159,7 @@ public class LockPatternView extends View {
|
||||
private int mErrorColor;
|
||||
private int mSuccessColor;
|
||||
private int mDotColor;
|
||||
private int mDotActivatedColor;
|
||||
|
||||
private final Interpolator mFastOutSlowInInterpolator;
|
||||
private final Interpolator mLinearOutSlowInInterpolator;
|
||||
@@ -237,6 +241,7 @@ public class LockPatternView extends View {
|
||||
float radius;
|
||||
float translationY;
|
||||
float alpha = 1f;
|
||||
float activationAnimationProgress;
|
||||
public float lineEndX = Float.MIN_VALUE;
|
||||
public float lineEndY = Float.MIN_VALUE;
|
||||
@Nullable
|
||||
@@ -330,6 +335,7 @@ public class LockPatternView extends View {
|
||||
mErrorColor = a.getColor(R.styleable.LockPatternView_errorColor, 0);
|
||||
mSuccessColor = a.getColor(R.styleable.LockPatternView_successColor, 0);
|
||||
mDotColor = a.getColor(R.styleable.LockPatternView_dotColor, mRegularColor);
|
||||
mDotActivatedColor = a.getColor(R.styleable.LockPatternView_dotActivatedColor, mDotColor);
|
||||
|
||||
int pathColor = a.getColor(R.styleable.LockPatternView_pathColor, mRegularColor);
|
||||
mPathPaint.setColor(pathColor);
|
||||
@@ -798,20 +804,52 @@ public class LockPatternView extends View {
|
||||
|
||||
private void startCellActivatedAnimation(Cell cell) {
|
||||
final CellState cellState = mCellStates[cell.row][cell.column];
|
||||
startRadiusAnimation(mDotSize/2, mDotSizeActivated/2, 96, mLinearOutSlowInInterpolator,
|
||||
cellState, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startRadiusAnimation(mDotSizeActivated/2, mDotSize/2, 192,
|
||||
mFastOutSlowInInterpolator,
|
||||
cellState, null);
|
||||
}
|
||||
});
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
startDotActivationColorAnimation(cellState);
|
||||
startLineEndAnimation(cellState, mInProgressX, mInProgressY,
|
||||
getCenterXForColumn(cell.column), getCenterYForRow(cell.row));
|
||||
startLineDisappearingAnimation(cellState);
|
||||
}
|
||||
|
||||
private void startDotActivationColorAnimation(CellState cellState) {
|
||||
ValueAnimator.AnimatorUpdateListener updateListener =
|
||||
new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
cellState.activationAnimationProgress =
|
||||
(float) valueAnimator.getAnimatedValue();
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
ValueAnimator activateAnimator = ValueAnimator.ofFloat(0f, 1f);
|
||||
ValueAnimator deactivateAnimator = ValueAnimator.ofFloat(1f, 0f);
|
||||
activateAnimator.addUpdateListener(updateListener);
|
||||
deactivateAnimator.addUpdateListener(updateListener);
|
||||
activateAnimator.setInterpolator(mFastOutSlowInInterpolator);
|
||||
deactivateAnimator.setInterpolator(mLinearOutSlowInInterpolator);
|
||||
|
||||
// Align dot animation duration with line fade out animation.
|
||||
activateAnimator.setDuration(DOT_ACTIVATION_DURATION_MILLIS);
|
||||
deactivateAnimator.setDuration(DOT_ACTIVATION_DURATION_MILLIS);
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.play(deactivateAnimator)
|
||||
.after(LINE_FADE_OUT_DELAY_MILLIS + LINE_FADE_OUT_DURATION_MILLIS
|
||||
- DOT_ACTIVATION_DURATION_MILLIS * 2)
|
||||
.after(activateAnimator);
|
||||
set.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -1295,7 +1333,8 @@ public class LockPatternView extends View {
|
||||
cellState.hwRadius, cellState.hwPaint);
|
||||
} else {
|
||||
drawCircle(canvas, (int) centerX, (int) centerY + translationY,
|
||||
cellState.radius, drawLookup[i][j], cellState.alpha);
|
||||
cellState.radius, drawLookup[i][j], cellState.alpha,
|
||||
cellState.activationAnimationProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1395,8 +1434,14 @@ public class LockPatternView extends View {
|
||||
* @param partOfPattern Whether this circle is part of the pattern.
|
||||
*/
|
||||
private void drawCircle(Canvas canvas, float centerX, float centerY, float radius,
|
||||
boolean partOfPattern, float alpha) {
|
||||
mPaint.setColor(getDotColor());
|
||||
boolean partOfPattern, float alpha, float activationAnimationProgress) {
|
||||
if (mFadePattern && !mInStealthMode) {
|
||||
int resultColor = ColorUtils.blendARGB(mDotColor, mDotActivatedColor,
|
||||
/* ratio= */ activationAnimationProgress);
|
||||
mPaint.setColor(resultColor);
|
||||
} else {
|
||||
mPaint.setColor(getDotColor());
|
||||
}
|
||||
mPaint.setAlpha((int) (alpha * 255));
|
||||
canvas.drawCircle(centerX, centerY, radius, mPaint);
|
||||
}
|
||||
|
||||
@@ -8658,6 +8658,8 @@
|
||||
<attr name="successColor" format="color|reference"/>
|
||||
<!-- The dot color -->
|
||||
<attr name="dotColor" format="color|reference"/>
|
||||
<!-- Color of the dot when it's activated -->
|
||||
<attr name="dotActivatedColor" format="color|reference"/>
|
||||
|
||||
</declare-styleable>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user