Created
July 25, 2019 13:47
-
-
Save dmoss18/442d9ab34f682a0e7bd94bb701822723 to your computer and use it in GitHub Desktop.
Label that renders a countdown timer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Xamarin.Forms; | |
namespace DK.InstantBetting.Views | |
{ | |
public partial class CountdownLabel : Label | |
{ | |
public static readonly BindableProperty TargetTimeProperty = | |
BindableProperty.Create("TargetTime", typeof(DateTime), typeof(CountdownLabel), DateTime.Now, propertyChanged: TargetTimeChanged); | |
public static readonly BindableProperty PrefixProperty = | |
BindableProperty.Create("Prefix", typeof(string), typeof(CountdownLabel), string.Empty); | |
public DateTime TargetTime | |
{ | |
get => (DateTime)GetValue(TargetTimeProperty); | |
set => SetValue(TargetTimeProperty, value); | |
} | |
public string Prefix | |
{ | |
get => (string)GetValue(PrefixProperty); | |
set => SetValue(PrefixProperty, value); | |
} | |
private bool _countdownRunning = false; | |
private bool _countdownValid = true; | |
private bool ShouldCountDown | |
{ | |
get => _countdownValid && TargetTime > DateTime.Now; | |
} | |
public CountdownLabel() | |
{ | |
InitializeComponent(); | |
UpdateTitle(); | |
StartCountdown(); | |
} | |
~CountdownLabel() | |
{ | |
StopCountdown(); | |
} | |
private static void TargetTimeChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
CountdownLabel countdownLabel = bindable as CountdownLabel; | |
if (countdownLabel == null) | |
{ | |
return; | |
} | |
countdownLabel.UpdateTitle(); | |
countdownLabel.StartCountdown(); | |
} | |
public void StartCountdown() | |
{ | |
_countdownValid = true; | |
if (_countdownRunning || !ShouldCountDown) | |
{ | |
return; | |
} | |
_countdownRunning = true; | |
Device.StartTimer(TimeSpan.FromSeconds(1), () => | |
{ | |
if (ShouldCountDown) | |
{ | |
UpdateTitle(); | |
} | |
_countdownRunning = ShouldCountDown; | |
return ShouldCountDown; | |
}); | |
} | |
public void StopCountdown() | |
{ | |
_countdownValid = false; | |
} | |
private void UpdateTitle() | |
{ | |
Text = ShouldCountDown ? | |
FormatTimeSpan(TargetTime.Subtract(DateTime.Now)) : | |
""; | |
} | |
private const string DaysFormat = @"dd\:hh\:mm\:ss"; | |
private const string HoursFormat = @"hh\:mm\:ss"; | |
private const string MinutesFormat = @"mm\:ss"; | |
private const string SecondsFormat = @"ss"; | |
private string FormatTimeSpan(TimeSpan span) | |
{ | |
string format; | |
if (span.Days > 0) | |
{ | |
format = DaysFormat; | |
} | |
else if (span.Hours > 0) | |
{ | |
format = HoursFormat; | |
} | |
else if (span.Minutes > 0) | |
{ | |
format = MinutesFormat; | |
} | |
else | |
{ | |
format = SecondsFormat; | |
} | |
return string.Format("{0}{1}", Prefix, span.ToString(format)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment