Countdown Timer in Xamain.Forms App

paramjitparamjit USMember ✭✭

I am trying to convert Xamarin.Android app to Xamarin.Forms, I nedd to have a countdown timer for exam format which will keep updating a label while we use the app. Once timer goes off message is displayed and another activity is opened. I had used follwoing code for Xamarin.Android app.

Can anyone help me understand how i can add this functionality to xamarin.forms app.

   public delegate void TickEvent(long millisUntilFinished);
     public delegate void FinishEvent();

    public class CountDown : CountDownTimer
    {
        public event TickEvent Tick;
        public event FinishEvent Finish;

        Activity m_owner;
        public CountDown(long totaltime, long interval, Activity owner): base(totaltime, interval)
        {
                m_owner = owner; 
        }
        public override void OnTick(long millisUntilFinished)
        {
            if (Tick != null)
            Tick(millisUntilFinished);
                long millis = millisUntilFinished;
                long hours = millis / (60 * 60 * 1000);
                long min = (millis / (60 * 1000)) % 60;
                long sec = (millis / 1000) % 60;
                TextView txtTime = m_owner.FindViewById<TextView>(Resource.Id.textTime);
                txtTime.Text = hours.ToString("00") + ":" + min.ToString("00") + ":" + sec.ToString("00");
        }
        public override void OnFinish()
        {
            var bulider = new AlertDialog.Builder(m_owner);
            bulider.SetMessage("Exam Time over");
            bulider.SetCancelable(false);
            bulider.SetPositiveButton("OK", delegate { });
            var dialog1 = bulider.Create();
            dialog1.Show(); 
            int res = 0;

            //start another activity
            m_owner.StartActivity (intent);

            if (Finish != null)
                Finish();     
    }

Answers

  • AmmarRashedAmmarRashed USMember ✭✭

    I have very similar problem and I found this post too. I couldn't get it though, if you do I would appreciate little help :D

  • paramjitparamjit USMember ✭✭

    This is how i implemented Timer

        public void StartTimer(int h, int m, int sec)
                {
                    hour = h;
                    mins = m;
                    counter = sec;
                    Device.StartTimer(new TimeSpan(0, 0, 1), () =>
                {
                    if (isTimerCancel == 1)
                    {
                        return false;
                    }
                    else 
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            counter = counter - 1;
                            if (counter < 0)
                            {
                                counter = 59;
                                mins = mins - 1;
                                if (mins < 0)
                                {
                                    mins = 59;
                                    hour = hour - 1;
                                    if (hour < 0)
                                    {
                                        hour = 0;
                                        mins = 0;
                                        counter = 0;
                                    }
                                }
                            }
    
                            lblTimer.Text = string.Format("{0:00}:{1:00}:{2:00}", hour, mins, counter);
                        });
                        if (hour == 0 && mins == 0 && counter==0)
                        {
                            //Code to call next form
                            Navigation.PushAsync(new Grade(canid, Exam, 0));
                            DisplayAlert("Exam", "Exam Time Over", "Close");
                            return false;
                        }
                        else
                        {
                            return true; 
                        }   
                    }
                });
    
            }
    

    Call to function

                        hour = 1;
                        counter = 0;
                        mins = 30;
                        isTimerCancel = 0;
                        StartTimer(hour, mins, counter);
    
  • JohnHardmanJohnHardman GBUniversity mod

    Be aware of the risk of timer drift and jerky countdown. Ensure that any UI code (including Navigation and DisplayAlert) is within a Device.BeginInvokeOnMainThread block. Consider what you want to happen if the user backgrounds your app or the lock screen kicks in. Also consider how you want to structure your code to handle the end of the countdown - do you want code inside your timer callback doing navigation and the display of alerts, or would that be better off done elsewhere (either will work, but still worth considering)?

  • AmmarRashedAmmarRashed USMember ✭✭

    I could get this done in a slightly different way I posted here

  • Vaka.GopiNadhReddyVaka.GopiNadhReddy USMember ✭✭✭

    Hi, I done this in Xamarin.Forms, Here is the code sample.......

    using System;
    using System.Threading;
    using Xamarin.Forms;

    namespace CountDownTimerSample
    {
    public class CountDownTimer : Label
    {
    CancellationTokenSource _CancellationTokenSource;
    public CountDownTimer()
    {
    _CancellationTokenSource = new CancellationTokenSource();
    FontFamily = "sans-serif-light";
    FontSize = 64;
    TextColor = Color.FromHex("#ffffff");
    }

    private void TimerStart()
    {
        int Min = CountDownMinutes;
        int Sec = CountDownSeconds;
        int TotalSec = (Min * 60) + Sec;
    
        CancellationTokenSource CTS = _CancellationTokenSource;
    
        Device.StartTimer(new TimeSpan(0, 0, 1), () =>
        {
            if (CTS.IsCancellationRequested)
            {
                return false;
            }
            else
            {
                if (TotalSec == 0)
                {
                    return false;
                }
                Device.BeginInvokeOnMainThread(() =>
                {
                    TotalSec = TotalSec - 1;
                    TimeSpan _TimeSpan = TimeSpan.FromSeconds(TotalSec);
                    Text = string.Format("{0:00}:{1:00}", _TimeSpan.Minutes, _TimeSpan.Seconds);
                });
                return true;
            }
        });
    }
    
    private void TimerStop()
    {
        Interlocked.Exchange(ref _CancellationTokenSource, new CancellationTokenSource()).Cancel();
    }
    
    static void OnTimerCancelChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
        ((CountDownTimer)bindable).TimerStop();
    }
    
    static void OnTimerTimeChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
        ((CountDownTimer)bindable).TimerStop();
        ((CountDownTimer)bindable).TimerStart();
    }
    
    public static readonly BindableProperty CountDownMinutesProperty = BindableProperty.Create("CountDownMinutes", typeof(int), typeof(CountDownTimer), 0, BindingMode.TwoWay, null, OnTimerTimeChanged);
    public int CountDownMinutes
    {
        get { return (int)base.GetValue(CountDownMinutesProperty); }
        set { base.SetValue(CountDownMinutesProperty, value); }
    }
    
    public static readonly BindableProperty CountDownSecondsProperty = BindableProperty.Create("CountDownSeconds", typeof(int), typeof(CountDownTimer), 0, BindingMode.TwoWay, null, OnTimerTimeChanged);
    public int CountDownSeconds
    {
        get { return (int)base.GetValue(CountDownSecondsProperty); }
        set { base.SetValue(CountDownSecondsProperty, value); }
    }
    
    public static readonly BindableProperty TimerCancelProperty = BindableProperty.Create("TimerCancel", typeof(bool), typeof(CountDownTimer), false, BindingMode.TwoWay, null, OnTimerCancelChanged);
    public bool TimerCancel
    {
        get { return (bool)base.GetValue(TimerCancelProperty); }
        set { base.SetValue(TimerCancelProperty, value); }
    }
    

    }
    }

  • Vaka.GopiNadhReddyVaka.GopiNadhReddy USMember ✭✭✭

    it's working fine in my case

Sign In or Register to comment.