149 lines
4.3 KiB
C#
149 lines
4.3 KiB
C#
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
|||
|
|
|||
|
using Android.Content;
|
|||
|
using Android.Graphics;
|
|||
|
using Android.Runtime;
|
|||
|
using Android.Util;
|
|||
|
using Android.Views;
|
|||
|
using Android.Views.Animations;
|
|||
|
using Android.Animation;
|
|||
|
using System;
|
|||
|
using Android.Support.V4.Content;
|
|||
|
|
|||
|
namespace MyDriving.Droid.Controls
|
|||
|
{
|
|||
|
public class RatingCircle : View
|
|||
|
{
|
|||
|
Bitmap bitmap;
|
|||
|
Canvas canvas;
|
|||
|
|
|||
|
RectF circleOuterBounds, circleInnerBounds;
|
|||
|
|
|||
|
Paint circlePaint, eraserPaint;
|
|||
|
Context context;
|
|||
|
float currentRating;
|
|||
|
float rating;
|
|||
|
|
|||
|
ValueAnimator timerAnimator;
|
|||
|
|
|||
|
public RatingCircle(IntPtr handle, JniHandleOwnership transfer)
|
|||
|
: base(handle, transfer)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public RatingCircle(Context context)
|
|||
|
: this(context, null)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
public RatingCircle(Context context, IAttributeSet attrs)
|
|||
|
: base(context, attrs)
|
|||
|
{
|
|||
|
Init(context, attrs);
|
|||
|
}
|
|||
|
|
|||
|
public RatingCircle(Context context, IAttributeSet attrs, int defStyle)
|
|||
|
: base(context, attrs, defStyle)
|
|||
|
{
|
|||
|
Init(context, attrs);
|
|||
|
}
|
|||
|
|
|||
|
public float Rating
|
|||
|
{
|
|||
|
get { return rating; }
|
|||
|
set
|
|||
|
{
|
|||
|
rating = value;
|
|||
|
currentRating = 0;
|
|||
|
if (PlayAnimation)
|
|||
|
Start(1);
|
|||
|
else
|
|||
|
Invalidate();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool PlayAnimation { get; set; } = true;
|
|||
|
|
|||
|
void Init(Context context, IAttributeSet attributeSet)
|
|||
|
{
|
|||
|
SetBackgroundColor(Color.Transparent);
|
|||
|
this.context = context;
|
|||
|
circlePaint = new Paint
|
|||
|
{
|
|||
|
Color = new Color(ContextCompat.GetColor(context, Resource.Color.accent)),
|
|||
|
AntiAlias = true
|
|||
|
};
|
|||
|
|
|||
|
eraserPaint = new Paint
|
|||
|
{
|
|||
|
AntiAlias = true,
|
|||
|
Color = Color.Transparent,
|
|||
|
};
|
|||
|
eraserPaint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.Clear));
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
|
|||
|
{
|
|||
|
if (w != oldw || h != oldh)
|
|||
|
{
|
|||
|
bitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888);
|
|||
|
bitmap.EraseColor(Color.Transparent);
|
|||
|
canvas = new Canvas(bitmap);
|
|||
|
}
|
|||
|
base.OnSizeChanged(w, h, oldw, oldh);
|
|||
|
UpdateBounds();
|
|||
|
}
|
|||
|
|
|||
|
void UpdateBounds()
|
|||
|
{
|
|||
|
var logicalDensity = context.Resources.DisplayMetrics.Density;
|
|||
|
var thickness = (int) Math.Ceiling(4*logicalDensity + .5f);
|
|||
|
|
|||
|
circleOuterBounds = new RectF(0, 0, Width, Height);
|
|||
|
circleInnerBounds = new RectF(
|
|||
|
circleOuterBounds.Left + thickness,
|
|||
|
circleOuterBounds.Top + thickness,
|
|||
|
circleOuterBounds.Right - thickness,
|
|||
|
circleOuterBounds.Bottom - thickness);
|
|||
|
|
|||
|
Invalidate();
|
|||
|
}
|
|||
|
|
|||
|
//make a perfect square
|
|||
|
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
|||
|
{
|
|||
|
var spec = widthMeasureSpec;
|
|||
|
base.OnMeasure(spec, spec);
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnDraw(Canvas canvas)
|
|||
|
{
|
|||
|
this.canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear);
|
|||
|
|
|||
|
|
|||
|
var sweepAngle = PlayAnimation ? (currentRating/100f)*360 : (Rating/100f)*360;
|
|||
|
if (sweepAngle > 0f)
|
|||
|
{
|
|||
|
this.canvas.DrawArc(circleOuterBounds, 270, sweepAngle, true, circlePaint);
|
|||
|
this.canvas.DrawOval(circleInnerBounds, eraserPaint);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
canvas.DrawBitmap(bitmap, 0, 0, null);
|
|||
|
}
|
|||
|
|
|||
|
void Start(long secs)
|
|||
|
{
|
|||
|
timerAnimator = ValueAnimator.OfFloat(0f, Rating);
|
|||
|
timerAnimator.SetDuration(Java.Util.Concurrent.TimeUnit.Seconds.ToMillis(secs));
|
|||
|
timerAnimator.SetInterpolator(new AccelerateInterpolator());
|
|||
|
timerAnimator.Update += (sender, e) =>
|
|||
|
{
|
|||
|
currentRating = (float) e.Animation.AnimatedValue;
|
|||
|
Invalidate();
|
|||
|
};
|
|||
|
timerAnimator.Start();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|