Show padlock on AOD

Bug: 111405682
Test: manual
Change-Id: I1e41cc332d676d977447327b75737795713f3040
This commit is contained in:
Lucas Dupin
2018-10-03 15:49:46 -07:00
parent 2e18958528
commit 117365db66
11 changed files with 59 additions and 425 deletions

View File

@@ -0,0 +1,26 @@
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32.0"
android:viewportHeight="32.0">
<path
android:pathData="M20.25,6.89C20.25,4.62 18.36,2.75 16,2.75C13.64,2.75 11.75,4.62 11.75,6.89V11.25H20.25V6.89ZM21.75,11.25V6.89C21.75,3.76 19.16,1.25 16,1.25C12.84,1.25 10.25,3.76 10.25,6.89V11.25H10C8.48,11.25 7.25,12.48 7.25,14V26C7.25,27.52 8.48,28.75 10,28.75H22C23.52,28.75 24.75,27.52 24.75,26V14C24.75,12.48 23.52,11.25 22,11.25H21.75ZM10,12.75C9.31,12.75 8.75,13.31 8.75,14V26C8.75,26.69 9.31,27.25 10,27.25H22C22.69,27.25 23.25,26.69 23.25,26V14C23.25,13.31 22.69,12.75 22,12.75H10ZM18,20C18,21.1 17.1,22 16,22C14.9,22 14,21.1 14,20C14,18.9 14.9,18 16,18C17.1,18 18,18.9 18,20Z"
android:fillType="evenOdd"
android:fillColor="?attr/wallpaperTextColor"/>
</vector>

View File

@@ -1,25 +0,0 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/wallpaperTextColor"
android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
</vector>

View File

@@ -0,0 +1,26 @@
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32.0"
android:viewportHeight="32.0">
<path
android:pathData="M21.75,6.89C21.75,4.62 23.64,2.75 26,2.75C28.36,2.75 30.25,4.62 30.25,6.89V12H31.75V6.89C31.75,3.76 29.16,1.25 26,1.25C22.84,1.25 20.25,3.76 20.25,6.89V11.25H10C8.48,11.25 7.25,12.48 7.25,14V26C7.25,27.52 8.48,28.75 10,28.75H22C23.52,28.75 24.75,27.52 24.75,26V14C24.75,12.48 23.52,11.25 22,11.25H21.75V6.89ZM10,12.75C9.31,12.75 8.75,13.31 8.75,14V26C8.75,26.69 9.31,27.25 10,27.25H22C22.69,27.25 23.25,26.69 23.25,26V14C23.25,13.31 22.69,12.75 22,12.75H10ZM18,20C18,21.1 17.1,22 16,22C14.9,22 14,21.1 14,20C14,18.9 14.9,18 16,18C17.1,18 18,18.9 18,20Z"
android:fillType="evenOdd"
android:fillColor="?attr/wallpaperTextColor"/>
</vector>

View File

@@ -88,7 +88,7 @@
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_height="@dimen/keyguard_affordance_height"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:src="@drawable/ic_lock"
android:contentDescription="@string/accessibility_unlock_button"
android:scaleType="center" />

View File

@@ -645,10 +645,6 @@
<dimen name="keyguard_affordance_height">56dp</dimen>
<dimen name="keyguard_affordance_width">56dp</dimen>
<!-- The width/height of the phone/camera/unlock icon drawable on keyguard. -->
<dimen name="keyguard_affordance_icon_height">24dp</dimen>
<dimen name="keyguard_affordance_icon_width">24dp</dimen>
<dimen name="keyguard_indication_margin_bottom">65dp</dimen>
<!-- The text size for battery level -->

View File

@@ -76,7 +76,7 @@ public class KeyguardAffordanceView extends ImageView {
private float mCircleStartRadius;
private float mMaxCircleSize;
private Animator mPreviewClipper;
private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT;
private float mRestingAlpha = 1f;
private boolean mSupportHardware;
private boolean mFinishing;
private boolean mLaunchingAffordance;

View File

@@ -36,7 +36,6 @@ import com.android.systemui.statusbar.KeyguardAffordanceView;
*/
public class KeyguardAffordanceHelper {
public static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.5f;
public static final long HINT_PHASE1_DURATION = 200;
private static final long HINT_PHASE2_DURATION = 350;
private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.25f;

View File

@@ -29,7 +29,6 @@ import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.hardware.biometrics.BiometricSourceType;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -41,6 +40,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricSourceType;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
@@ -54,7 +54,6 @@ import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
@@ -68,16 +67,14 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.EventLogTags;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -705,8 +702,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
startFinishDozeAnimationElement(mLeftAffordanceView, delay);
delay += DOZE_ANIMATION_STAGGER_DELAY;
}
startFinishDozeAnimationElement(mLockIcon, delay);
delay += DOZE_ANIMATION_STAGGER_DELAY;
if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
startFinishDozeAnimationElement(mRightAffordanceView, delay);
}
@@ -823,10 +818,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
updateLeftAffordanceIcon();
if (dozing) {
mLockIcon.setVisibility(INVISIBLE);
mOverlayContainer.setVisibility(INVISIBLE);
} else {
mLockIcon.setVisibility(VISIBLE);
mOverlayContainer.setVisibility(VISIBLE);
if (animate) {
startFinishDozeAnimation();

View File

@@ -51,7 +51,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
private boolean mScreenOn;
private boolean mLastScreenOn;
private Drawable mUserAvatarIcon;
private TrustDrawable mTrustDrawable;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
private boolean mHasFingerPrintIcon;
@@ -62,27 +61,9 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
public LockIcon(Context context, AttributeSet attrs) {
super(context, attrs);
mTrustDrawable = new TrustDrawable(context);
setBackground(mTrustDrawable);
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (isShown()) {
mTrustDrawable.start();
} else {
mTrustDrawable.stop();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mTrustDrawable.stop();
}
@Override
public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
mUserAvatarIcon = picture;
@@ -110,9 +91,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
final int density = newConfig.densityDpi;
if (density != mDensity) {
mDensity = density;
mTrustDrawable.stop();
mTrustDrawable = new TrustDrawable(getContext());
setBackground(mTrustDrawable);
update();
}
}
@@ -122,18 +100,9 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
}
public void update(boolean force) {
boolean visible = isShown()
&& KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
if (visible) {
mTrustDrawable.start();
} else {
mTrustDrawable.stop();
}
int state = getState();
boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
mHasFaceUnlockIcon = state == STATE_FACE_UNLOCK;
boolean useAdditionalPadding = anyFingerprintIcon;
boolean trustHidden = anyFingerprintIcon;
if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
|| mScreenOn != mLastScreenOn || force) {
int iconAnimRes =
@@ -142,16 +111,10 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
boolean isAnim = iconAnimRes != -1;
if (iconAnimRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
anyFingerprintIcon = true;
useAdditionalPadding = true;
trustHidden = true;
} else if (iconAnimRes == R.drawable.trusted_state_to_error_animation) {
anyFingerprintIcon = true;
useAdditionalPadding = false;
trustHidden = true;
} else if (iconAnimRes == R.drawable.error_to_trustedstate_animation) {
anyFingerprintIcon = true;
useAdditionalPadding = false;
trustHidden = false;
}
Drawable icon;
@@ -166,20 +129,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
? (AnimatedVectorDrawable) icon
: null;
int iconHeight = getResources().getDimensionPixelSize(
R.dimen.keyguard_affordance_icon_height);
int iconWidth = getResources().getDimensionPixelSize(
R.dimen.keyguard_affordance_icon_width);
if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
|| icon.getIntrinsicWidth() != iconWidth)) {
icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
}
setPaddingRelative(0, 0, 0, useAdditionalPadding
? getResources().getDimensionPixelSize(
R.dimen.fingerprint_icon_additional_padding)
: 0);
setRestingAlpha(
anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
setImageDrawable(icon, false);
if (mHasFaceUnlockIcon) {
announceForAccessibility(getContext().getString(
@@ -204,9 +153,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
mLastScreenOn = mScreenOn;
}
// Hide trust circle when fingerprint is running.
boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
mTrustDrawable.setTrustManaged(trustManaged);
updateClickability();
}
@@ -250,27 +196,21 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
private Drawable getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
int iconRes;
switch (state) {
case STATE_FINGERPRINT:
case STATE_LOCKED:
iconRes = R.drawable.ic_lock_24dp;
iconRes = R.drawable.ic_lock;
break;
case STATE_LOCK_OPEN:
if (mUnlockMethodCache.isTrustManaged() && mUnlockMethodCache.isTrusted()
&& mUserAvatarIcon != null) {
return mUserAvatarIcon;
} else {
iconRes = R.drawable.ic_lock_open_24dp;
iconRes = R.drawable.ic_lock_open;
}
break;
case STATE_FACE_UNLOCK:
iconRes = R.drawable.ic_face_unlock;
break;
case STATE_FINGERPRINT:
// If screen is off and device asleep, use the draw on animation so the first frame
// gets drawn.
iconRes = screenOn && deviceInteractive
? R.drawable.ic_fingerprint
: R.drawable.lockscreen_fingerprint_draw_on_animation;
break;
case STATE_FINGERPRINT_ERROR:
iconRes = R.drawable.ic_fingerprint_error;
break;
@@ -319,29 +259,4 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
return STATE_LOCKED;
}
}
/**
* A wrapper around another Drawable that overrides the intrinsic size.
*/
private static class IntrinsicSizeDrawable extends InsetDrawable {
private final int mIntrinsicWidth;
private final int mIntrinsicHeight;
public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
super(drawable, 0);
mIntrinsicWidth = intrinsicWidth;
mIntrinsicHeight = intrinsicHeight;
}
@Override
public int getIntrinsicWidth() {
return mIntrinsicWidth;
}
@Override
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}
}
}

View File

@@ -124,8 +124,6 @@ public class NotificationPanelView extends PanelView implements
private static final int CAP_HEIGHT = 1456;
private static final int FONT_HEIGHT = 2163;
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
static final String COUNTER_PANEL_OPEN = "panel_open";
static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
@@ -1780,13 +1778,9 @@ public class NotificationPanelView extends PanelView implements
KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
if (active && !mUnlockIconActive && mTracking) {
lockIcon.setImageAlpha(1.0f, true, 150, Interpolators.FAST_OUT_LINEAR_IN, null);
lockIcon.setImageScale(LOCK_ICON_ACTIVE_SCALE, true, 150,
Interpolators.FAST_OUT_LINEAR_IN);
} else if (!active && mUnlockIconActive && mTracking) {
lockIcon.setImageAlpha(lockIcon.getRestingAlpha(), true /* animate */,
150, Interpolators.FAST_OUT_LINEAR_IN, null);
lockIcon.setImageScale(1.0f, true, 150,
Interpolators.FAST_OUT_LINEAR_IN);
}
mUnlockIconActive = active;
}

View File

@@ -1,290 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.animation.Interpolator;
import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
public class TrustDrawable extends Drawable {
private static final long ENTERING_FROM_UNSET_START_DELAY = 200;
private static final long VISIBLE_DURATION = 1000;
private static final long EXIT_DURATION = 500;
private static final long ENTER_DURATION = 500;
private static final int ALPHA_VISIBLE_MIN = 0x26;
private static final int ALPHA_VISIBLE_MAX = 0x4c;
private static final int STATE_UNSET = -1;
private static final int STATE_GONE = 0;
private static final int STATE_ENTERING = 1;
private static final int STATE_VISIBLE = 2;
private static final int STATE_EXITING = 3;
private int mAlpha;
private boolean mAnimating;
private int mCurAlpha;
private float mCurInnerRadius;
private Animator mCurAnimator;
private int mState = STATE_UNSET;
private Paint mPaint;
private boolean mTrustManaged;
private final float mInnerRadiusVisibleMin;
private final float mInnerRadiusVisibleMax;
private final float mInnerRadiusExit;
private final float mInnerRadiusEnter;
private final float mThickness;
private final Animator mVisibleAnimator;
public TrustDrawable(Context context) {
Resources r = context.getResources();
mInnerRadiusVisibleMin = r.getDimension(R.dimen.trust_circle_inner_radius_visible_min);
mInnerRadiusVisibleMax = r.getDimension(R.dimen.trust_circle_inner_radius_visible_max);
mInnerRadiusExit = r.getDimension(R.dimen.trust_circle_inner_radius_exit);
mInnerRadiusEnter = r.getDimension(R.dimen.trust_circle_inner_radius_enter);
mThickness = r.getDimension(R.dimen.trust_circle_thickness);
mCurInnerRadius = mInnerRadiusEnter;
mVisibleAnimator = makeVisibleAnimator();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor));
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mThickness);
}
@Override
public void draw(Canvas canvas) {
int newAlpha = (mCurAlpha * mAlpha) / 256;
if (newAlpha == 0) {
return;
}
final Rect r = getBounds();
mPaint.setAlpha(newAlpha);
canvas.drawCircle(r.exactCenterX(), r.exactCenterY(), mCurInnerRadius, mPaint);
}
@Override
public void setAlpha(int alpha) {
mAlpha = alpha;
}
@Override
public int getAlpha() {
return mAlpha;
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
public void start() {
if (!mAnimating) {
mAnimating = true;
updateState(true);
invalidateSelf();
}
}
public void stop() {
if (mAnimating) {
mAnimating = false;
if (mCurAnimator != null) {
mCurAnimator.cancel();
mCurAnimator = null;
}
mState = STATE_UNSET;
mCurAlpha = 0;
mCurInnerRadius = mInnerRadiusEnter;
invalidateSelf();
}
}
public void setTrustManaged(boolean trustManaged) {
if (trustManaged == mTrustManaged && mState != STATE_UNSET) return;
mTrustManaged = trustManaged;
updateState(true);
}
private void updateState(boolean allowTransientState) {
if (!mAnimating) {
return;
}
int nextState = mState;
if (mState == STATE_UNSET) {
nextState = mTrustManaged ? STATE_ENTERING : STATE_GONE;
} else if (mState == STATE_GONE) {
if (mTrustManaged) nextState = STATE_ENTERING;
} else if (mState == STATE_ENTERING) {
if (!mTrustManaged) nextState = STATE_EXITING;
} else if (mState == STATE_VISIBLE) {
if (!mTrustManaged) nextState = STATE_EXITING;
} else if (mState == STATE_EXITING) {
if (mTrustManaged) nextState = STATE_ENTERING;
}
if (!allowTransientState) {
if (nextState == STATE_ENTERING) nextState = STATE_VISIBLE;
if (nextState == STATE_EXITING) nextState = STATE_GONE;
}
if (nextState != mState) {
if (mCurAnimator != null) {
mCurAnimator.cancel();
mCurAnimator = null;
}
if (nextState == STATE_GONE) {
mCurAlpha = 0;
mCurInnerRadius = mInnerRadiusEnter;
} else if (nextState == STATE_ENTERING) {
mCurAnimator = makeEnterAnimator(mCurInnerRadius, mCurAlpha);
if (mState == STATE_UNSET) {
mCurAnimator.setStartDelay(ENTERING_FROM_UNSET_START_DELAY);
}
} else if (nextState == STATE_VISIBLE) {
mCurAlpha = ALPHA_VISIBLE_MAX;
mCurInnerRadius = mInnerRadiusVisibleMax;
mCurAnimator = mVisibleAnimator;
} else if (nextState == STATE_EXITING) {
mCurAnimator = makeExitAnimator(mCurInnerRadius, mCurAlpha);
}
mState = nextState;
if (mCurAnimator != null) {
mCurAnimator.start();
}
invalidateSelf();
}
}
private Animator makeVisibleAnimator() {
return makeAnimators(mInnerRadiusVisibleMax, mInnerRadiusVisibleMin,
ALPHA_VISIBLE_MAX, ALPHA_VISIBLE_MIN, VISIBLE_DURATION,
Interpolators.ACCELERATE_DECELERATE,
true /* repeating */, false /* stateUpdateListener */);
}
private Animator makeEnterAnimator(float radius, int alpha) {
return makeAnimators(radius, mInnerRadiusVisibleMax,
alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, Interpolators.LINEAR_OUT_SLOW_IN,
false /* repeating */, true /* stateUpdateListener */);
}
private Animator makeExitAnimator(float radius, int alpha) {
return makeAnimators(radius, mInnerRadiusExit,
alpha, 0, EXIT_DURATION, Interpolators.FAST_OUT_SLOW_IN,
false /* repeating */, true /* stateUpdateListener */);
}
private Animator makeAnimators(float startRadius, float endRadius,
int startAlpha, int endAlpha, long duration, Interpolator interpolator,
boolean repeating, boolean stateUpdateListener) {
ValueAnimator alphaAnimator = configureAnimator(
ValueAnimator.ofInt(startAlpha, endAlpha),
duration, mAlphaUpdateListener, interpolator, repeating);
ValueAnimator sizeAnimator = configureAnimator(
ValueAnimator.ofFloat(startRadius, endRadius),
duration, mRadiusUpdateListener, interpolator, repeating);
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnimator, sizeAnimator);
if (stateUpdateListener) {
set.addListener(new StateUpdateAnimatorListener());
}
return set;
}
private ValueAnimator configureAnimator(ValueAnimator animator, long duration,
ValueAnimator.AnimatorUpdateListener updateListener, Interpolator interpolator,
boolean repeating) {
animator.setDuration(duration);
animator.addUpdateListener(updateListener);
animator.setInterpolator(interpolator);
if (repeating) {
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
}
return animator;
}
private final ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurAlpha = (int) animation.getAnimatedValue();
invalidateSelf();
}
};
private final ValueAnimator.AnimatorUpdateListener mRadiusUpdateListener =
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurInnerRadius = (float) animation.getAnimatedValue();
invalidateSelf();
}
};
private class StateUpdateAnimatorListener extends AnimatorListenerAdapter {
boolean mCancelled;
@Override
public void onAnimationStart(Animator animation) {
mCancelled = false;
}
@Override
public void onAnimationCancel(Animator animation) {
mCancelled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
if (!mCancelled) {
updateState(false);
}
}
}
}