SwipeProgressBar.java revision c7f272243076297526887a3bbccf7a0ec51cc30a
1e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira/* 2e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Copyright (C) 2013 The Android Open Source Project 3e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * 4e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 5e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * you may not use this file except in compliance with the License. 6e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * You may obtain a copy of the License at 7e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * 8e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 9e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * 10e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Unless required by applicable law or agreed to in writing, software 11e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 12e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * See the License for the specific language governing permissions and 14e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * limitations under the License. 15e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 16e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 17e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereirapackage android.support.v4.widget; 18e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 19e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.graphics.Canvas; 20e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.graphics.Paint; 21e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.graphics.Rect; 22e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.graphics.RectF; 23e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.support.v4.view.ViewCompat; 24e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.view.View; 25e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.view.animation.AnimationUtils; 26e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereiraimport android.view.animation.Interpolator; 27e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 28e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 29e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira/** 30e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Custom progress bar that shows a cycle of colors as widening circles that 31e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * overdraw each other. When finished, the bar is cleared from the inside out as 32e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * the main cycle continues. Before running, this can also indicate how close 33e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * the user is to triggering something (e.g. how far they need to pull down to 34e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * trigger a refresh). 35e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 36e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereirafinal class SwipeProgressBar { 37e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 38e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Default progress animation colors are grays. 39e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final static int COLOR1 = 0xB3000000; 40e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final static int COLOR2 = 0x80000000; 41e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final static int COLOR3 = 0x4d000000; 42e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final static int COLOR4 = 0x1a000000; 43e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 44e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // The duration of the animation cycle. 45e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private static final int ANIMATION_DURATION_MS = 2000; 46e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 47e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // The duration of the animation to clear the bar. 48e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private static final int FINISH_ANIMATION_DURATION_MS = 1000; 49e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 50e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Interpolator for varying the speed of the animation. 51e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private static final Interpolator INTERPOLATOR = BakedBezierInterpolator.getInstance(); 52e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 53e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final Paint mPaint = new Paint(); 54e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private final RectF mClipRect = new RectF(); 55e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private float mTriggerPercentage; 56e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private long mStartTime; 57e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private long mFinishTime; 58e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private boolean mRunning; 59e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 60e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Colors used when rendering the animation, 61e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private int mColor1; 62e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private int mColor2; 63e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private int mColor3; 64e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private int mColor4; 65e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private View mParent; 66e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 67e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private Rect mBounds = new Rect(); 68e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 69e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira public SwipeProgressBar(View parent) { 70e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mParent = parent; 71e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor1 = COLOR1; 72e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor2 = COLOR2; 73e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor3 = COLOR3; 74e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor4 = COLOR4; 75e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 76e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 77e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 78e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Set the four colors used in the progress animation. The first color will 79e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * also be the color of the bar that grows in response to a user swipe 80e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * gesture. 81e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * 82e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param color1 Integer representation of a color. 83e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param color2 Integer representation of a color. 84e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param color3 Integer representation of a color. 85e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param color4 Integer representation of a color. 86e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 87e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void setColorScheme(int color1, int color2, int color3, int color4) { 88e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor1 = color1; 89e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor2 = color2; 90e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor3 = color3; 91e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mColor4 = color4; 92e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 93e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 94e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 95e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Update the progress the user has made toward triggering the swipe 96e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * gesture. and use this value to update the percentage of the trigger that 97e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * is shown. 98e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 99e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void setTriggerPercentage(float triggerPercentage) { 100e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mTriggerPercentage = triggerPercentage; 101e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mStartTime = 0; 102e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira ViewCompat.postInvalidateOnAnimation(mParent); 103e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 104e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 105e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 106e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Start showing the progress animation. 107e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 108e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void start() { 109e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (!mRunning) { 110e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mTriggerPercentage = 0; 111e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mStartTime = AnimationUtils.currentAnimationTimeMillis(); 112e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mRunning = true; 113e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mParent.postInvalidate(); 114e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 115e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 116e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 117e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 118e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Stop showing the progress animation. 119e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 120e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void stop() { 121e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (mRunning) { 122e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mTriggerPercentage = 0; 123e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mFinishTime = AnimationUtils.currentAnimationTimeMillis(); 124e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mRunning = false; 125e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mParent.postInvalidate(); 126e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 127e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 128e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 129e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 130e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @return Return whether the progress animation is currently running. 131e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 132e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira boolean isRunning() { 133e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira return mRunning || mFinishTime > 0; 134e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 135e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 136e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void draw(Canvas canvas) { 137e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira final int width = mBounds.width(); 138e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira final int height = mBounds.height(); 139e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira final int cx = width / 2; 140e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira final int cy = height / 2; 141c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira boolean drawTriggerWhileFinishing = false; 142e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira int restoreCount = canvas.save(); 143e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.clipRect(mBounds); 144e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 145e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (mRunning || (mFinishTime > 0)) { 146e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira long now = AnimationUtils.currentAnimationTimeMillis(); 147e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira long elapsed = (now - mStartTime) % ANIMATION_DURATION_MS; 148e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira long iterations = (now - mStartTime) / ANIMATION_DURATION_MS; 149e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f)); 150e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 151e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // If we're not running anymore, that means we're running through 152e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // the finish animation. 153e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (!mRunning) { 154e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // If the finish animation is done, don't draw anything, and 155e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // don't repost. 156e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if ((now - mFinishTime) >= FINISH_ANIMATION_DURATION_MS) { 157e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mFinishTime = 0; 158e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira return; 159e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 160e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 161e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Otherwise, use a 0 opacity alpha layer to clear the animation 162e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // from the inside out. This layer will prevent the circles from 163e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // drawing within its bounds. 164e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira long finishElapsed = (now - mFinishTime) % FINISH_ANIMATION_DURATION_MS; 165e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float finishProgress = (finishElapsed / (FINISH_ANIMATION_DURATION_MS / 100f)); 166e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = (finishProgress / 100f); 167e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Radius of the circle is half of the screen. 168e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float clearRadius = width / 2 * INTERPOLATOR.getInterpolation(pct); 169e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mClipRect.set(cx - clearRadius, 0, cx + clearRadius, height); 170e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.saveLayerAlpha(mClipRect, 0, 0); 171c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira // Only draw the trigger if there is a space in the center of 172c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira // this refreshing view that needs to be filled in by the 173c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira // trigger. If the progress view is just still animating, let it 174c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira // continue animating. 175c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira drawTriggerWhileFinishing = true; 176e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 177e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 178e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // First fill in with the last color that would have finished drawing. 179e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (iterations == 0) { 180e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawColor(mColor1); 181e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } else { 182e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (rawProgress >= 0 && rawProgress < 25) { 183e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawColor(mColor4); 184e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } else if (rawProgress >= 25 && rawProgress < 50) { 185e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawColor(mColor1); 186e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } else if (rawProgress >= 50 && rawProgress < 75) { 187e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawColor(mColor2); 188e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } else { 189e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawColor(mColor3); 190e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 191e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 192e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 193e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Then draw up to 4 overlapping concentric circles of varying radii, based on how far 194e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // along we are in the cycle. 195e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // progress 0-50 draw mColor2 196e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // progress 25-75 draw mColor3 197e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // progress 50-100 draw mColor4 198e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // progress 75 (wrap to 25) draw mColor1 199e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if ((rawProgress >= 0 && rawProgress <= 25)) { 200e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = (((rawProgress + 25) * 2) / 100f); 201e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawCircle(canvas, cx, cy, mColor1, pct); 202e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 203e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (rawProgress >= 0 && rawProgress <= 50) { 204e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = ((rawProgress * 2) / 100f); 205e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawCircle(canvas, cx, cy, mColor2, pct); 206e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 207e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (rawProgress >= 25 && rawProgress <= 75) { 208e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = (((rawProgress - 25) * 2) / 100f); 209e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawCircle(canvas, cx, cy, mColor3, pct); 210e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 211e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (rawProgress >= 50 && rawProgress <= 100) { 212e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = (((rawProgress - 50) * 2) / 100f); 213e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawCircle(canvas, cx, cy, mColor4, pct); 214e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 215e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if ((rawProgress >= 75 && rawProgress <= 100)) { 216e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float pct = (((rawProgress - 75) * 2) / 100f); 217e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawCircle(canvas, cx, cy, mColor1, pct); 218e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 219c7f272243076297526887a3bbccf7a0ec51cc30aMindy Pereira if (mTriggerPercentage > 0 && drawTriggerWhileFinishing) { 220e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // There is some portion of trigger to draw. Restore the canvas, 221e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // then draw the trigger. Otherwise, the trigger does not appear 222e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // until after the bar has finished animating and appears to 223e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // just jump in at a larger width than expected. 224e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.restoreToCount(restoreCount); 225e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira restoreCount = canvas.save(); 226e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.clipRect(mBounds); 227e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawTrigger(canvas, cx, cy); 228e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 229e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Keep running until we finish out the last cycle. 230e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira ViewCompat.postInvalidateOnAnimation(mParent); 231e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } else { 232e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira // Otherwise if we're in the middle of a trigger, draw that. 233e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira if (mTriggerPercentage > 0 && mTriggerPercentage <= 1.0) { 234e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira drawTrigger(canvas, cx, cy); 235e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 236e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 237e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.restoreToCount(restoreCount); 238e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 239e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 240e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private void drawTrigger(Canvas canvas, int cx, int cy) { 241e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mPaint.setColor(mColor1); 242e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawCircle(cx, cy, cx * mTriggerPercentage, mPaint); 243e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 244e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 245e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 246e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Draws a circle centered in the view. 247e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * 248e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param canvas the canvas to draw on 249e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param cx the center x coordinate 250e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param cy the center y coordinate 251e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param color the color to draw 252e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * @param pct the percentage of the view that the circle should cover 253e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 254e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira private void drawCircle(Canvas canvas, float cx, float cy, int color, float pct) { 255e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mPaint.setColor(color); 256e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.save(); 257e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.translate(cx, cy); 258e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira float radiusScale = INTERPOLATOR.getInterpolation(pct); 259e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.scale(radiusScale, radiusScale); 260e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.drawCircle(0, 0, cx, mPaint); 261e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira canvas.restore(); 262e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 263e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira 264e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira /** 265e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira * Set the drawing bounds of this SwipeProgressBar. 266e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira */ 267e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira void setBounds(int left, int top, int right, int bottom) { 268e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mBounds.left = left; 269e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mBounds.top = top; 270e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mBounds.right = right; 271e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira mBounds.bottom = bottom; 272e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira } 273e9a361cf082bf8fbe908d1abfdc327209ec01d82Mindy Pereira}