void draw(Canvas canvas) { final int width = mBounds.width(); final int height = mBounds.height(); final int cx = width / 2; final int cy = height / 2; boolean drawTriggerWhileFinishing = false; int restoreCount = canvas.save(); canvas.clipRect(mBounds); if (mRunning || (mFinishTime > 0)) { long now = AnimationUtils.currentAnimationTimeMillis(); long elapsed = (now - mStartTime) % ANIMATION_DURATION_MS; long iterations = (now - mStartTime) / ANIMATION_DURATION_MS; float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f)); // If we're not running anymore, that means we're running through // the finish animation. if (!mRunning) { // If the finish animation is done, don't draw anything, and // don't repost. if ((now - mFinishTime) >= FINISH_ANIMATION_DURATION_MS) { mFinishTime = 0; return; } // Otherwise, use a 0 opacity alpha layer to clear the animation // from the inside out. This layer will prevent the circles from // drawing within its bounds. long finishElapsed = (now - mFinishTime) % FINISH_ANIMATION_DURATION_MS; float finishProgress = (finishElapsed / (FINISH_ANIMATION_DURATION_MS / 100f)); float pct = (finishProgress / 100f); // Radius of the circle is half of the screen. float clearRadius = width / 2 * INTERPOLATOR.getInterpolation(pct); mClipRect.set(cx - clearRadius, 0, cx + clearRadius, height); canvas.saveLayerAlpha(mClipRect, 0, 0); // Only draw the trigger if there is a space in the center of // this refreshing view that needs to be filled in by the // trigger. If the progress view is just still animating, let it // continue animating. drawTriggerWhileFinishing = true; } // First fill in with the last color that would have finished drawing. if (iterations == 0) { canvas.drawColor(mColor1); } else { if (rawProgress >= 0 && rawProgress < 25) { canvas.drawColor(mColor4); } else if (rawProgress >= 25 && rawProgress < 50) { canvas.drawColor(mColor1); } else if (rawProgress >= 50 && rawProgress < 75) { canvas.drawColor(mColor2); } else { canvas.drawColor(mColor3); } } // Then draw up to 4 overlapping concentric circles of varying radii, based on how far // along we are in the cycle. // progress 0-50 draw mColor2 // progress 25-75 draw mColor3 // progress 50-100 draw mColor4 // progress 75 (wrap to 25) draw mColor1 if ((rawProgress >= 0 && rawProgress <= 25)) { float pct = (((rawProgress + 25) * 2) / 100f); drawCircle(canvas, cx, cy, mColor1, pct); } if (rawProgress >= 0 && rawProgress <= 50) { float pct = ((rawProgress * 2) / 100f); drawCircle(canvas, cx, cy, mColor2, pct); } if (rawProgress >= 25 && rawProgress <= 75) { float pct = (((rawProgress - 25) * 2) / 100f); drawCircle(canvas, cx, cy, mColor3, pct); } if (rawProgress >= 50 && rawProgress <= 100) { float pct = (((rawProgress - 50) * 2) / 100f); drawCircle(canvas, cx, cy, mColor4, pct); } if ((rawProgress >= 75 && rawProgress <= 100)) { float pct = (((rawProgress - 75) * 2) / 100f); drawCircle(canvas, cx, cy, mColor1, pct); } if (mTriggerPercentage > 0 && drawTriggerWhileFinishing) { // There is some portion of trigger to draw. Restore the canvas, // then draw the trigger. Otherwise, the trigger does not appear // until after the bar has finished animating and appears to // just jump in at a larger width than expected. canvas.restoreToCount(restoreCount); restoreCount = canvas.save(); canvas.clipRect(mBounds); drawTrigger(canvas, cx, cy); } // Keep running until we finish out the last cycle. ViewCompat.postInvalidateOnAnimation( mParent, mBounds.left, mBounds.top, mBounds.right, mBounds.bottom); } else { // Otherwise if we're in the middle of a trigger, draw that. if (mTriggerPercentage > 0 && mTriggerPercentage <= 1.0) { drawTrigger(canvas, cx, cy); } } canvas.restoreToCount(restoreCount); }
void draw(Canvas paramCanvas) { int i = this.mBounds.width(); int i1 = this.mBounds.height(); int m = i / 2; int n = i1 / 2; int k = 0; int j = paramCanvas.save(); paramCanvas.clipRect(this.mBounds); float f1; if ((this.mRunning) || (this.mFinishTime > 0L)) { long l1 = AnimationUtils.currentAnimationTimeMillis(); long l2 = this.mStartTime; long l3 = (l1 - this.mStartTime) / 2000L; f1 = (float) ((l1 - l2) % 2000L) / 20.0F; float f2; if (!this.mRunning) { if (l1 - this.mFinishTime >= 1000L) { this.mFinishTime = 0L; return; } f2 = (float) ((l1 - this.mFinishTime) % 1000L) / 10.0F / 100.0F; f2 = i / 2 * INTERPOLATOR.getInterpolation(f2); this.mClipRect.set(m - f2, 0.0F, m + f2, i1); paramCanvas.saveLayerAlpha(this.mClipRect, 0, 0); k = 1; } if (l3 == 0L) { paramCanvas.drawColor(this.mColor1); if ((f1 >= 0.0F) && (f1 <= 25.0F)) { f2 = (25.0F + f1) * 2.0F / 100.0F; drawCircle(paramCanvas, m, n, this.mColor1, f2); } if ((f1 >= 0.0F) && (f1 <= 50.0F)) { f2 = 2.0F * f1 / 100.0F; drawCircle(paramCanvas, m, n, this.mColor2, f2); } if ((f1 >= 25.0F) && (f1 <= 75.0F)) { f2 = (f1 - 25.0F) * 2.0F / 100.0F; drawCircle(paramCanvas, m, n, this.mColor3, f2); } if ((f1 >= 50.0F) && (f1 <= 100.0F)) { f2 = (f1 - 50.0F) * 2.0F / 100.0F; drawCircle(paramCanvas, m, n, this.mColor4, f2); } if ((f1 >= 75.0F) && (f1 <= 100.0F)) { f1 = (f1 - 75.0F) * 2.0F / 100.0F; drawCircle(paramCanvas, m, n, this.mColor1, f1); } i = j; if (this.mTriggerPercentage > 0.0F) { i = j; if (k != 0) { paramCanvas.restoreToCount(j); i = paramCanvas.save(); paramCanvas.clipRect(this.mBounds); drawTrigger(paramCanvas, m, n); } } ViewCompat.postInvalidateOnAnimation( this.mParent, this.mBounds.left, this.mBounds.top, this.mBounds.right, this.mBounds.bottom); } } while (true) { paramCanvas.restoreToCount(i); return; if ((f1 >= 0.0F) && (f1 < 25.0F)) { paramCanvas.drawColor(this.mColor4); break; } if ((f1 >= 25.0F) && (f1 < 50.0F)) { paramCanvas.drawColor(this.mColor1); break; } if ((f1 >= 50.0F) && (f1 < 75.0F)) { paramCanvas.drawColor(this.mColor2); break; } paramCanvas.drawColor(this.mColor3); break; i = j; if (this.mTriggerPercentage <= 0.0F) continue; i = j; if (this.mTriggerPercentage > 1.0D) continue; drawTrigger(paramCanvas, m, n); i = j; } }