private void DrawTrigger(Canvas canvas, int cx, int cy) { _paint.Color = ColorUtils.FromUint(_color1); canvas.DrawCircle(cx, cy, cx * _triggerPercentage, _paint); }
private void DrawCircle(Canvas canvas, float cx, float cy, uint color, float pct) { DrawCircle(canvas, cx, cy, ColorUtils.FromUint(color), pct); }
public void Draw(Canvas canvas) { var clipPath = new Path(); clipPath.AddRoundRect(_bounds, _cornerRadius, _cornerRadius, Path.Direction.Cw); int width = (int)_bounds.Width(); int height = (int)_bounds.Height(); int cx = width / 2; int cy = height / 2; bool drawTriggerWhileFinishing = false; int restoreCount = canvas.Save(); canvas.ClipPath(clipPath); if (_running || _finishTime > 0) { long now = AnimationUtils.CurrentAnimationTimeMillis(); long elapsed = (now - _startTime) % ANIMATION_DURATION_MS; long iterations = (now - _startTime) / ANIMATION_DURATION_MS; float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f)); if (!_running) { if ((now - _finishTime) >= FINISH_ANIMATION_DURATION_MS) { _finishTime = 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 finishEplapsed = (now - _finishTime) % FINISH_ANIMATION_DURATION_MS; float finishProgress = (finishEplapsed / (FINISH_ANIMATION_DURATION_MS / 100f)); float pct = finishProgress / 100f; float clearRadius = width / 2 * _interpolator.GetInterpolation(pct); _rectF.Set(cx - clearRadius, 0, cx + clearRadius, height); canvas.SaveLayerAlpha(_rectF, 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(ColorUtils.FromUint(_color1)); } else { if (rawProgress >= 0 && rawProgress < 25) { canvas.DrawColor(ColorUtils.FromUint(_color4)); } else if (rawProgress >= 25 && rawProgress < 50) { canvas.DrawColor(ColorUtils.FromUint(_color1)); } else if (rawProgress >= 50 && rawProgress < 75) { canvas.DrawColor(ColorUtils.FromUint(_color2)); } else { canvas.DrawColor(ColorUtils.FromUint(_color3)); } } // 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, _color1, pct); } if (rawProgress >= 0 && rawProgress <= 50) { float pct = ((rawProgress * 2) / 100f); DrawCircle(canvas, cx, cy, _color2, pct); } if (rawProgress >= 25 && rawProgress <= 75) { float pct = (((rawProgress - 25) * 2) / 100f); DrawCircle(canvas, cx, cy, _color3, pct); } if (rawProgress >= 50 && rawProgress <= 100) { float pct = (((rawProgress - 50) * 2) / 100f); DrawCircle(canvas, cx, cy, _color4, pct); } if ((rawProgress >= 75 && rawProgress <= 100)) { float pct = (((rawProgress - 75) * 2) / 100f); DrawCircle(canvas, cx, cy, _color1, pct); } if (_triggerPercentage > 0 && drawTriggerWhileFinishing) { canvas.RestoreToCount(restoreCount); restoreCount = canvas.Save(); canvas.ClipPath(clipPath); DrawTrigger(canvas, cx, cy); } ViewCompat.PostInvalidateOnAnimation(_parent); } else if (_triggerPercentage > 0 && _triggerPercentage < 1.0) { DrawTrigger(canvas, cx, cy); } canvas.RestoreToCount(restoreCount); }