Hello, I am a big fan of Microsoft live tiles (Windows phone days)
So I made my own
<StackLayout Padding="0">
<control:LiveTileControl
Title="My live tile"
LiveTileBackgroundColor="Green"
TitleColor="White"
TitleFontAtributes="Bold"
TitleFontSize="14"
TitlePosition="LowerLeft"
RefreshRate="5"
IconSource="{Static font:FluentUI.people_12_regular}"
TransparencyPercentage="30" />
</StackLayout>
C#
using Microsoft.Maui.Controls.Shapes;
namespace LiveTileControl.Controls;
public partial class LiveTileControl : ContentView {
#region Bindiable Properties
public static readonly BindableProperty TransparencyPercentageProperty = BindableProperty.Create(
nameof(TransparencyPercentage),
typeof(double),
typeof(LiveTileControl),
100.0,
propertyChanged: OnTransparencyPercentageChanged);
public static readonly BindableProperty LiveTileBackGroundProperty = BindableProperty.Create(
nameof(LiveTileBackgroundColor),
typeof(Color),
typeof(LiveTileControl),
Colors.Transparent);
public static readonly BindableProperty IconSourceProperty = BindableProperty.Create(
nameof(IconSource),
typeof(string),
typeof(LiveTileControl));
public static readonly BindableProperty RefreshRateProperty = BindableProperty.Create(
nameof(RefreshRate),
typeof(int),
typeof(LiveTileControl),
30);
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
nameof(Title),
typeof(string),
typeof(LiveTileControl));
public static readonly BindableProperty TitleFontFamilyProperty = BindableProperty.Create(
nameof(TitleFontFamily),
typeof(string),
typeof(LiveTileControl),
"Default");
public static readonly BindableProperty TitlePositionProperty = BindableProperty.Create(
nameof(TitlePosition),
typeof(TitlePositionEnum),
typeof(LiveTileControl),
TitlePositionEnum.LowerLeft);
public static readonly BindableProperty TitleColorProperty = BindableProperty.Create(
nameof(TitleColor),
typeof(Color),
typeof(LiveTileControl),
Colors.Black);
public static readonly BindableProperty TitleFontSizeProperty = BindableProperty.Create(
nameof(TitleFontSize),
typeof(int),
typeof(LiveTileControl));
public static readonly BindableProperty TitleFontAtributesProperty = BindableProperty.Create(
nameof(TitleFontAtributes),
typeof(FontAttributes),
typeof(LiveTileControl));
public TitlePositionEnum TitlePosition {
get => (TitlePositionEnum)GetValue(TitlePositionProperty);
set => SetValue(TitlePositionProperty, value);
}
private static void OnTransparencyPercentageChanged(BindableObject bindable, object oldValue, object newValue) {
if(bindable is LiveTileControl control && newValue is double transparency) {
control.UpdateBackgroundTransparency(transparency);
}
}
private void UpdateBackgroundTransparency(double transparency) {
float alpha = (float)Math.Clamp(transparency / 100.0, 0.0, 1.0);
var baseColor = BackgroundColor != null ? BackgroundColor : Colors.Transparent;
LiveTileBackgroundColor = baseColor.WithAlpha(alpha);
}
public double TransparencyPercentage {
get => (double)GetValue(TransparencyPercentageProperty);
set => SetValue(TransparencyPercentageProperty, value);
}
public Color LiveTileBackgroundColor {
get => (Color)GetValue(LiveTileBackGroundProperty);
set => SetValue(LiveTileBackGroundProperty, value);
}
public string IconSource {
get => (string)GetValue(IconSourceProperty);
set => SetValue(IconSourceProperty, value);
}
public int RefreshRate {
get => (int)GetValue(RefreshRateProperty);
set => SetValue(RefreshRateProperty, value);
}
public string Title {
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public string TitleFontFamily {
get => (string)GetValue(TitleFontFamilyProperty);
set => SetValue(TitleFontFamilyProperty, value);
}
public Color TitleColor {
get => (Color)GetValue(TitleColorProperty);
set => SetValue(TitleColorProperty, value);
}
public int TitleFontSize {
get => (int)GetValue(TitleFontSizeProperty);
set => SetValue(TitleFontSizeProperty, value);
}
public FontAttributes TitleFontAtributes {
get => (FontAttributes)GetValue(TitleFontAtributesProperty);
set => SetValue(TitleFontAtributesProperty, value);
}
#endregion
#region This enum will be use for the position o the title
public enum TitlePositionEnum {
UpperLeft,
UpperRight,
LowerLeft,
LowerRight,
Center
}
#endregion
private View CreateIcon() {
return new Image {
Source = IconSource,
WidthRequest = 48,
HeightRequest = 48,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
}
private View CreateText() {
var label = new Label {
Text = Title,
TextColor = TitleColor,
FontFamily = TitleFontFamily,
FontSize = TitleFontSize,
FontAttributes = TitleFontAtributes
};
UpdateTextAlligment(label);
return label;
}
private void UpdateTextAlligment(Label label) {
switch(TitlePosition) {
case TitlePositionEnum.UpperLeft:
label.HorizontalOptions = LayoutOptions.Start;
label.VerticalOptions = LayoutOptions.Start;
break;
case TitlePositionEnum.UpperRight:
label.HorizontalOptions = LayoutOptions.End;
label.VerticalOptions = LayoutOptions.Start;
break;
case TitlePositionEnum.LowerLeft:
label.HorizontalOptions = LayoutOptions.Start;
label.VerticalOptions = LayoutOptions.End;
break;
case TitlePositionEnum.LowerRight:
label.HorizontalOptions = LayoutOptions.End;
label.VerticalOptions = LayoutOptions.End;
break;
case TitlePositionEnum.Center:
label.HorizontalOptions = LayoutOptions.Center;
label.VerticalOptions = LayoutOptions.Center;
break;
default:
label.HorizontalOptions = LayoutOptions.Center;
label.VerticalOptions = LayoutOptions.Center;
break;
}
}
public async Task UpdateAnimation() {
await this.ScaleTo(1.1, 150, Easing.CubicOut);
await this.FadeTo(0.5, 150, Easing.CubicIn);
await this.ScaleTo(1, 150, Easing.CubicOut);
await this.FadeTo(1, 150, Easing.CubicIn);
}
public async void StartAutoRefresh() {
var timer = new PeriodicTimer(TimeSpan.FromSeconds(RefreshRate));
while(await timer.WaitForNextTickAsync()) {
await Dispatcher.DispatchAsync(async () => {
await UpdateAnimation();
string newData = await FetchData();
UpdateContent(newData);
});
}
}
private async Task<string> FetchData() {
try {
using var httpClient = new HttpClient();
var response = await httpClient.GetStringAsync("https://jsonplaceholder.typicode.com/posts/1");
return "Sample Data Fetched!";
} catch(Exception ex) {
Console.WriteLine($"Error fetching data: {ex.Message}");
return "Error Fetching Data";
}
}
private void UpdateContent(string newData) {
if(Content is Border border && border.Content is Grid grid) {
foreach(var child in grid.Children) {
if(child is Label label) {
label.Text = newData;
}
}
}
}
public LiveTileControl() {
var grid = new Grid {
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill
};
grid.Children.Add(CreateIcon());
grid.Children.Add(CreateText());
var border = new Border {
StrokeShape = new RoundRectangle {
CornerRadius = new CornerRadius(10)
},
BackgroundColor = LiveTileBackgroundColor,
Content = grid
};
Content = border;
}
}
Is still don't work as expended

is supposed to be green, with 30% transparency, animate, show the icon, print into console evetime the data is updated
also, I included the icon of fluentUI that Microsoft included in .Net (Microsoft Created the class but did not include the font itself,

and I modify the main
fonts.AddFont("FluentSystemIcons-Regular.ttf", "FluentUI");