Timer

lllnnnlllnnn USMember

I created stopWatch view on android platform(whith xamarin). Then rendering to xamarin forms. I have problem whith invalidationg speed.
This is my code.
ANDROID VIEW

class StopWatch : Android.Views.View
{
byte miliseconds = 0;
byte seconds = 0;
byte minutes = 0;
byte hour = 0;
Handler handler;
bool IsStarted = false;
bool aninateState =false;
int step = 3;
int startDeg = 360;
private Android.Graphics.Color textColor;

    public Android.Graphics.Color TextColor
    {
        get
        {
            return textColor;
        }
        set
        {

            textColor = value;

        }
    }
    public StopWatch(Context context):base(context)
    {
        handler = new Handler(
            (msg) =>
            {
                if (msg.What == 1)
                {
                    Invalidate();
                }
                if (msg.What == 2)
                {
                    Invalidate();
                }
            }
        );           
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    public void OnStart()
    {
        if (IsStarted==false)
        {
            IsStarted = true;
            StartTimer();
        }

    }
    public string GetTime()
    {
        return ConvertTime(miliseconds, seconds, minutes, hour);
    }
    public void OnStop()
    {
        IsStarted = false;         
    }
    public void Reset()
    {
        miliseconds = 0;
        seconds = 0;
        minutes = 0;
        hour = 0;
    }
    private async void StartTimer()
    {
       await Task.Run(
            () =>
            {
                while (IsStarted==true)
                { 
                miliseconds++;
                if (miliseconds == 10)
                {
                    miliseconds = 0;
                    if (seconds != 60)
                    {
                        seconds++;                           
                    }
                    else
                    {
                        seconds++;                            
                        minutes++;
                        if (minutes == 60)
                        {

                            hour++;
                            minutes = 0;
                        }

                    }
                }
                if (seconds == 60)
                {

                    minutes++;
                    seconds = 0;
                        if (minutes == 60)
                        {


                            hour++;
                            minutes = 0;
                            AnimateMinuteSector();
                        }
                }
                Thread.Sleep(100);
                handler.SendMessage(new Message()
                    {
                        What = 1
                    });

                }
            }
        );
    }
    private string ConvertTime(byte miliseconds, byte seconds, byte minutes, byte hour)
    {
        string sec;
        string min;
        string hou;
        if (seconds < 10)
        {
            sec = "0" + seconds;
        }
        else
        {
            sec = seconds.ToString();
        }
        if (hour < 10)
        {
            hou = "0" + hour;
        }
        else
        {
            hou = hour.ToString();
        }
        if (minutes < 10)
        {
            min = "0" + minutes;
        }
        else
        {
            min = minutes.ToString();
        }
        return $"{hou}:{min}:{sec}:{miliseconds}";
    }

    protected override void OnDraw(Canvas canvas)
    {
        base.OnDraw(canvas);
        var colors = new int[] { new Android.Graphics.Color(0, 0, 0), new Android.Graphics.Color(255, 255, 255) };
        var points = new float[] { 0.8f, 1f };

        string time = ConvertTime(miliseconds, seconds, minutes, hour);
        Paint backgroundPaint = new Paint()
        {
            AntiAlias = true,
            StrokeWidth = 10,
        };
        Paint textPaint = new Paint()
        {
            AntiAlias = true,
            TextSize = 0.15f * Height,
            TextAlign = Paint.Align.Center,
            Color = textColor
        };

        Typeface tf = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, "liquidcr.ttf");

        textPaint.SetTypeface(tf);
        textPaint.SetShadowLayer(10, 0, 0, Android.Graphics.Color.Black);

        backgroundPaint.SetStyle(Paint.Style.Fill);
        backgroundPaint.Color = Android.Graphics.Color.Argb(50, 255, 255, 255);

        canvas.DrawArc(new RectF(60, 60, Height - 60, Width - 60), 270, hour * 6, true, backgroundPaint);


        canvas.DrawArc(new RectF(45, 45, Height - 45, Width - 45), 270, minutes * 6, true, backgroundPaint);
        if (aninateState == true)
        {
            canvas.DrawArc(new RectF(45, 45, Height - 45, Width - 45), 270, startDeg, true, backgroundPaint);
        }

        backgroundPaint.SetStyle(Paint.Style.Stroke);
        backgroundPaint.Color = Android.Graphics.Color.Gray;
        backgroundPaint.SetShadowLayer(20, 0, 0, Android.Graphics.Color.Black);
        canvas.DrawArc(new RectF(40, 40, Height - 40, Width - 40), 270, 360, false, backgroundPaint);

        backgroundPaint.SetShadowLayer(5, 0, 0, Android.Graphics.Color.Black);
        backgroundPaint.StrokeWidth = 30;
        RadialGradient radGrad = new RadialGradient(Width / 2, Height / 2, Height / 2, colors, points,Shader.TileMode.Clamp);
        backgroundPaint.SetShader(radGrad);
        canvas.DrawArc(new RectF(30, 30, Height - 30, Width - 30), 270, 360, false, backgroundPaint);

        backgroundPaint.SetShader(null);
        backgroundPaint.StrokeWidth = 10;
        canvas.DrawArc(new RectF(20, 20, Height - 20, Width - 20), 270, 360, false, backgroundPaint);

        backgroundPaint.Color = Android.Graphics.Color.DarkOrange;
        canvas.DrawArc(new RectF(20, 20, Height - 20, Width - 20), 270, seconds * 6, false, backgroundPaint);
        canvas.DrawText(time, Width/2, Height/2, textPaint);
    }

    private async void AnimateMinuteSector()
    {
        aninateState = true;
        await Task.Run(() =>
        {
            while (aninateState)
            {
                startDeg -= step;

                Thread.Sleep(10);
                handler.SendMessage(new Message()
                {
                    What = 2
                });
                if (startDeg <= 0)
                {
                    aninateState = false;
                }
            }

        });
    }
}

}

RENDERER

[assembly: ExportRenderer(typeof(TrainingApp.CustomView.StopWatch), typeof(StopWatchRenderer))]
namespace TrainingApp.Droid.Renders
{
class StopWatchRenderer : ViewRenderer<TrainingApp.CustomView.StopWatch, StopWatch>
{
protected override void OnElementChanged(ElementChangedEventArgs<TrainingApp.CustomView.StopWatch> e)
{
base.OnElementChanged(e);
if (Control == null)
{

                StopWatch stopWatch = new StopWatch(Context);

                SetNativeControl(stopWatch);
                SetTextColor();
            }
            Element.Start += (s, args) =>
            {
                Control.OnStart();
            };
            Element.Stop += (s, args) =>
            {
                Control.OnStop();
            };
            Element.GetTime += (s, args) =>
            {
                Element.Time = Control.GetTime();
            };
        }


        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e.PropertyName == TrainingApp.CustomView.StopWatch.TextColorProperty.PropertyName)
            {
                SetTextColor();
            }
        }

        private void SetTextColor()
        {
            Android.Graphics.Color andrColor = Android.Graphics.Color.Gray;

            if (Element.TextColor != Xamarin.Forms.Color.Default)
            {
                Xamarin.Forms.Color color = Element.TextColor;
                andrColor = Android.Graphics.Color.Argb(
                    (byte)(color.A * 255),
                    (byte)(color.R * 255),
                    (byte)(color.G * 255),
                    (byte)(color.B * 255));
            }
            Control.TextColor = andrColor;
        }


    }

}

XAMARIN FOMS PROGECT

namespace TrainingApp.CustomView
{
public class StopWatch:View
{
public static readonly BindableProperty TextColorProperty = BindableProperty.Create("TextColor", typeof(Color), typeof(StopWatch), Color.DarkOrange);
public static readonly BindableProperty TimeProperty = BindableProperty.Create("Time", typeof(string), typeof(StopWatch), "0");

    public Color TextColor
    {
        get
        {
            return (Color)GetValue(TextColorProperty);
        }
        set
        {
            SetValue(TextColorProperty, value);
        }
    }
    public string Time
    {
        get
        {
            OnGetTime();
            return (string)GetValue(TimeProperty);
        }
        set
        {
            SetValue(TimeProperty, value);
        }
    }
    public event EventHandler Start;
    public event EventHandler Stop;
    public event EventHandler GetTime;
    public StopWatch()
    {
        BackgroundColor = Color.Transparent;
        HorizontalOptions = LayoutOptions.Center;
        VerticalOptions = LayoutOptions.Center;
    }
    protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
    {
        return new SizeRequest(new Size(300,300));
    }
    public void OnStart()
    {
        if (Start != null)
        {
            Start(this, new EventArgs());
        }
    }

    public void OnStop()
    {
        if (Stop != null)
        {
            Stop(this, new EventArgs());
        }
    }
    private void OnGetTime()
    {
        if (GetTime != null)
        {
            GetTime(this, new EventArgs());
        }

    }
}

}

Sign In or Register to comment.