12e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos/* 22e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * Copyright (C) 2014 The Android Open Source Project 32e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * 42e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 52e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * you may not use this file except in compliance with the License. 62e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * You may obtain a copy of the License at 72e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * 82e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * http://www.apache.org/licenses/LICENSE-2.0 92e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * 102e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * Unless required by applicable law or agreed to in writing, software 112e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 122e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * See the License for the specific language governing permissions and 142e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos * limitations under the License 152e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos */ 162e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 172e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roospackage com.android.systemui.statusbar.phone; 182e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 192e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.animation.Animator; 202e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.animation.AnimatorListenerAdapter; 212e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.animation.AnimatorSet; 222e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.animation.ValueAnimator; 232e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.content.Context; 242e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.content.res.Resources; 252e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.Canvas; 262e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.Color; 272e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.ColorFilter; 282e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.Paint; 292e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.PixelFormat; 302e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.Rect; 312e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.graphics.drawable.Drawable; 322e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roosimport android.view.animation.Interpolator; 332e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 3484c381b614feda2333df7858a550fb62148f3d41Lucas Dupinimport com.android.settingslib.Utils; 35c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.Interpolators; 36c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinekimport com.android.systemui.R; 37c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek 382e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roospublic class TrustDrawable extends Drawable { 392e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 402e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final long ENTERING_FROM_UNSET_START_DELAY = 200; 412e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final long VISIBLE_DURATION = 1000; 422e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final long EXIT_DURATION = 500; 432e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final long ENTER_DURATION = 500; 442e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 452e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int ALPHA_VISIBLE_MIN = 0x26; 462e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int ALPHA_VISIBLE_MAX = 0x4c; 472e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 482e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int STATE_UNSET = -1; 492e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int STATE_GONE = 0; 502e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int STATE_ENTERING = 1; 512e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int STATE_VISIBLE = 2; 522e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private static final int STATE_EXITING = 3; 532e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 542e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private int mAlpha; 552e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private boolean mAnimating; 562e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 572e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private int mCurAlpha; 582e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private float mCurInnerRadius; 592e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Animator mCurAnimator; 602e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private int mState = STATE_UNSET; 612e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Paint mPaint; 622e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private boolean mTrustManaged; 632e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 642e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final float mInnerRadiusVisibleMin; 652e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final float mInnerRadiusVisibleMax; 662e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final float mInnerRadiusExit; 672e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final float mInnerRadiusEnter; 682e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final float mThickness; 692e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 702e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final Animator mVisibleAnimator; 712e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 722e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public TrustDrawable(Context context) { 732e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos Resources r = context.getResources(); 742e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mInnerRadiusVisibleMin = r.getDimension(R.dimen.trust_circle_inner_radius_visible_min); 752e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mInnerRadiusVisibleMax = r.getDimension(R.dimen.trust_circle_inner_radius_visible_max); 762e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mInnerRadiusExit = r.getDimension(R.dimen.trust_circle_inner_radius_exit); 772e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mInnerRadiusEnter = r.getDimension(R.dimen.trust_circle_inner_radius_enter); 782e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mThickness = r.getDimension(R.dimen.trust_circle_thickness); 792e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 802e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurInnerRadius = mInnerRadiusEnter; 812e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 822e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mVisibleAnimator = makeVisibleAnimator(); 832e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 842e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mPaint = new Paint(); 852e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mPaint.setStyle(Paint.Style.STROKE); 86a360e1e70ff5bb40a950bfe6dd3250415ec99edaLucas Dupin mPaint.setColor(Utils.getColorAttr(context, R.attr.wallpaperTextColor)); 872e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mPaint.setAntiAlias(true); 882e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mPaint.setStrokeWidth(mThickness); 892e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 902e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 912e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 922e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void draw(Canvas canvas) { 932e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos int newAlpha = (mCurAlpha * mAlpha) / 256; 942e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (newAlpha == 0) { 952e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return; 962e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 972e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos final Rect r = getBounds(); 982e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mPaint.setAlpha(newAlpha); 992e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos canvas.drawCircle(r.exactCenterX(), r.exactCenterY(), mCurInnerRadius, mPaint); 1002e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1012e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1022e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 1032e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void setAlpha(int alpha) { 1042e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mAlpha = alpha; 1052e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1062e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1072e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 1082e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public int getAlpha() { 1092e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return mAlpha; 1102e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1112e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1122e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 113bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik public void setColorFilter(ColorFilter colorFilter) { 1142e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos throw new UnsupportedOperationException("not implemented"); 1152e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1162e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1172e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 1182e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public int getOpacity() { 1192e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return PixelFormat.TRANSLUCENT; 1202e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1212e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1222e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void start() { 1232e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (!mAnimating) { 1242e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mAnimating = true; 1252e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos updateState(true); 1261540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos invalidateSelf(); 1272e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1282e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1292e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1302e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void stop() { 1312e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mAnimating) { 1322e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mAnimating = false; 1332e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mCurAnimator != null) { 1342e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator.cancel(); 1352e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator = null; 1362e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1372e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mState = STATE_UNSET; 1382e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAlpha = 0; 1392e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurInnerRadius = mInnerRadiusEnter; 1401540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos invalidateSelf(); 1412e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1422e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1432e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1442e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void setTrustManaged(boolean trustManaged) { 1452e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (trustManaged == mTrustManaged && mState != STATE_UNSET) return; 1462e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mTrustManaged = trustManaged; 1471540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos updateState(true); 1482e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1492e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1501540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos private void updateState(boolean allowTransientState) { 1511540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos if (!mAnimating) { 1521540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos return; 1531540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos } 1541540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos 1552e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos int nextState = mState; 1562e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mState == STATE_UNSET) { 1572e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos nextState = mTrustManaged ? STATE_ENTERING : STATE_GONE; 1582e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (mState == STATE_GONE) { 1592e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mTrustManaged) nextState = STATE_ENTERING; 1602e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (mState == STATE_ENTERING) { 1612e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (!mTrustManaged) nextState = STATE_EXITING; 1622e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (mState == STATE_VISIBLE) { 1632e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (!mTrustManaged) nextState = STATE_EXITING; 1642e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (mState == STATE_EXITING) { 1652e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mTrustManaged) nextState = STATE_ENTERING; 1662e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1671540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos if (!allowTransientState) { 1682e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (nextState == STATE_ENTERING) nextState = STATE_VISIBLE; 1692e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (nextState == STATE_EXITING) nextState = STATE_GONE; 1702e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1712e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1722e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (nextState != mState) { 1732e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mCurAnimator != null) { 1742e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator.cancel(); 1752e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator = null; 1762e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1772e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1782e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (nextState == STATE_GONE) { 1792e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAlpha = 0; 1802e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurInnerRadius = mInnerRadiusEnter; 1812e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (nextState == STATE_ENTERING) { 1822e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator = makeEnterAnimator(mCurInnerRadius, mCurAlpha); 1832e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mState == STATE_UNSET) { 1842e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator.setStartDelay(ENTERING_FROM_UNSET_START_DELAY); 1852e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1862e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (nextState == STATE_VISIBLE) { 1872e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAlpha = ALPHA_VISIBLE_MAX; 1882e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurInnerRadius = mInnerRadiusVisibleMax; 1892e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator = mVisibleAnimator; 1902e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } else if (nextState == STATE_EXITING) { 1912e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator = makeExitAnimator(mCurInnerRadius, mCurAlpha); 1922e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1932e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 1942e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mState = nextState; 1952e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (mCurAnimator != null) { 1962e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAnimator.start(); 1972e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 1981540da4624ebdf674784a970892d4d4b7b64e775Adrian Roos invalidateSelf(); 1992e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2002e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2012e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2022e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Animator makeVisibleAnimator() { 2032e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return makeAnimators(mInnerRadiusVisibleMax, mInnerRadiusVisibleMin, 2042e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ALPHA_VISIBLE_MAX, ALPHA_VISIBLE_MIN, VISIBLE_DURATION, 205c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek Interpolators.ACCELERATE_DECELERATE, 2062e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos true /* repeating */, false /* stateUpdateListener */); 2072e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2082e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2092e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Animator makeEnterAnimator(float radius, int alpha) { 2102e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return makeAnimators(radius, mInnerRadiusVisibleMax, 211c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, Interpolators.LINEAR_OUT_SLOW_IN, 2122e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos false /* repeating */, true /* stateUpdateListener */); 2132e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2142e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2152e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Animator makeExitAnimator(float radius, int alpha) { 2162e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return makeAnimators(radius, mInnerRadiusExit, 217c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek alpha, 0, EXIT_DURATION, Interpolators.FAST_OUT_SLOW_IN, 2182e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos false /* repeating */, true /* stateUpdateListener */); 2192e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2202e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2212e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private Animator makeAnimators(float startRadius, float endRadius, 2222e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos int startAlpha, int endAlpha, long duration, Interpolator interpolator, 2232e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos boolean repeating, boolean stateUpdateListener) { 2242e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ValueAnimator alphaAnimator = configureAnimator( 2252e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ValueAnimator.ofInt(startAlpha, endAlpha), 2262e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos duration, mAlphaUpdateListener, interpolator, repeating); 2272e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ValueAnimator sizeAnimator = configureAnimator( 2282e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ValueAnimator.ofFloat(startRadius, endRadius), 2292e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos duration, mRadiusUpdateListener, interpolator, repeating); 2302e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2312e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos AnimatorSet set = new AnimatorSet(); 2322e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos set.playTogether(alphaAnimator, sizeAnimator); 2332e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (stateUpdateListener) { 2342e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos set.addListener(new StateUpdateAnimatorListener()); 2352e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2362e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return set; 2372e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2382e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2392e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private ValueAnimator configureAnimator(ValueAnimator animator, long duration, 2402e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos ValueAnimator.AnimatorUpdateListener updateListener, Interpolator interpolator, 2412e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos boolean repeating) { 2422e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos animator.setDuration(duration); 2432e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos animator.addUpdateListener(updateListener); 2442e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos animator.setInterpolator(interpolator); 2452e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (repeating) { 2462e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos animator.setRepeatCount(ValueAnimator.INFINITE); 2472e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos animator.setRepeatMode(ValueAnimator.REVERSE); 2482e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2492e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos return animator; 2502e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2512e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2522e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener = 2532e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos new ValueAnimator.AnimatorUpdateListener() { 2542e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 2552e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void onAnimationUpdate(ValueAnimator animation) { 2562e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurAlpha = (int) animation.getAnimatedValue(); 2572e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos invalidateSelf(); 2582e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2592e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos }; 2602e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2612e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private final ValueAnimator.AnimatorUpdateListener mRadiusUpdateListener = 2622e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos new ValueAnimator.AnimatorUpdateListener() { 2632e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 2642e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void onAnimationUpdate(ValueAnimator animation) { 2652e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCurInnerRadius = (float) animation.getAnimatedValue(); 2662e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos invalidateSelf(); 2672e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2682e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos }; 2692e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2702e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos private class StateUpdateAnimatorListener extends AnimatorListenerAdapter { 2712e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos boolean mCancelled; 2722e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2732e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 2742e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void onAnimationStart(Animator animation) { 2752e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCancelled = false; 2762e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2772e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2782e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 2792e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void onAnimationCancel(Animator animation) { 2802e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos mCancelled = true; 2812e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2822e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos 2832e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos @Override 2842e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos public void onAnimationEnd(Animator animation) { 2852e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos if (!mCancelled) { 2862e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos updateState(false); 2872e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2882e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2892e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos } 2902e3ccbb37e21eb40308f83fb185209773147f78dAdrian Roos} 291