using Android.Animation; using Android.Graphics; using Android.Graphics.Drawables; using System; using AColor = Android.Graphics.Color; namespace Gallery.Droid.Renderers.AppShellSection { public class AppColorChangeRevealDrawable : AnimationDrawable { readonly Point _center; float _progress; bool _disposed; ValueAnimator _animator; internal AColor StartColor { get; } internal AColor EndColor { get; } public AppColorChangeRevealDrawable(AColor startColor, AColor endColor, Point center) : base() { StartColor = startColor; EndColor = endColor; if (StartColor != EndColor) { _animator = ValueAnimator.OfFloat(0, 1); _animator.SetInterpolator(new Android.Views.Animations.DecelerateInterpolator()); _animator.SetDuration(500); _animator.Update += OnUpdate; _animator.Start(); _center = center; } else { _progress = 1; } } public override void Draw(Canvas canvas) { if (_disposed) return; if (_progress == 1) { canvas.DrawColor(EndColor); return; } canvas.DrawColor(StartColor); var bounds = Bounds; float centerX = _center.X; float centerY = _center.Y; float width = bounds.Width(); float distanceFromCenter = Math.Abs(width / 2 - _center.X); float radius = (width / 2 + distanceFromCenter) * 1.1f; var paint = new Paint { Color = EndColor }; canvas.DrawCircle(centerX, centerY, radius * _progress, paint); } void OnUpdate(object sender, ValueAnimator.AnimatorUpdateEventArgs e) { _progress = (float)e.Animation.AnimatedValue; InvalidateSelf(); } protected override void Dispose(bool disposing) { if (_disposed) return; _disposed = true; if (disposing) { if (_animator != null) { _animator.Update -= OnUpdate; _animator.Cancel(); _animator.Dispose(); _animator = null; } } base.Dispose(disposing); } } }