Implement The Generic Badge View In Xamarin.Forms

Introduction

In this article, I will explain the Generic Badge in Xamarin forms. We can implement the badge for Android, iOS, and UWP. The plugin creates a custom renderer for each platform and a custom attached property for adding tab bar badges, which can be bound in XF shared code.

Important Note
Make sure to install the below package in your Xamarin, the forms shared/core project, as well as platform specific projects. The v2.2.0 package also contains an XF Badge view, based on an XF Frame View. It can be added to any layout and bound using the usual approach. The generic badge view can also be added to custom NavigationPage.TitleView layouts.

Nuget Package

Install-Package Plugin. Badge

Step 1

Create a new XAML file and follow the below code to help you to connect with the view model.

<ContentPage.BindingContext>
    <viewModels: GenericBadgeTabViewModel />
</ContentPage.BindingContext>

Step 2

Create the badge control for viewing/updating the badge count values with help of binding.

<views:Badge Grid.Row="0"
    VerticalOptions="Center"
    BadgeText="{Binding Count}"
    BadgeFontAttributes="{Binding FontAttributes}"
    BadgeFontSize="{Binding FontSize}"
    BackgroundColor="{Binding BadgeColor}"
    BadgeTextColor="{Binding BadgeTextColor}" />

Step 3

Write the below full code in created XAML files, and don’t forget to import the xmlns values at the top of XAML files.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:views="clr-namespace:Plugin.Badge.Abstractions;assembly=Plugin.Badge.Abstractions" xmlns:viewModels="clr-namespace:XamarinBadge" x:Class="XamarinBadge.MainPage">
  <ContentPage.BindingContext>
    <viewModels:GenericBadgeTabViewModel />
  </ContentPage.BindingContext>
  <NavigationPage.TitleView>
    <StackLayout HorizontalOptions="Center" Orientation="Horizontal">
      <Label Text="Custom View" FontSize="16" TextColor="Black" FontAttributes="Bold" VerticalTextAlignment="Center" />
      <Image Source="tabicon.png" VerticalOptions="Center" WidthRequest="16" HeightRequest="16" />
      <views:Badge Grid.Row="0" VerticalOptions="Center" BadgeText="{Binding Count}" BadgeFontAttributes="{Binding FontAttributes}" BadgeFontSize="{Binding FontSize}" BackgroundColor="{Binding BadgeColor}" BadgeTextColor="{Binding BadgeTextColor}" />
    </StackLayout>
  </NavigationPage.TitleView>
  <ContentPage.Content>
    <StackLayout>
      <Grid HorizontalOptions="Center" Padding="0,20,0,0">
        <Grid.RowDefinitions>
          <RowDefinition />
          <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Image Source="tabicon.png" WidthRequest="50" HeightRequest="50" />
        <Image Grid.Row="1" Source="tabicon.png" WidthRequest="50" HeightRequest="50" />
        <views:Badge Grid.Row="0" Grid.RowSpan="2" BadgeText="{Binding Count}" BadgeFontAttributes="{Binding FontAttributes}" BackgroundColor="{Binding BadgeColor}" BadgeTextColor="{Binding BadgeTextColor}" WidthRequest="30" HeightRequest="40" BadgeFontSize="14" />
      </Grid>
      <StackLayout Orientation="Horizontal">
        <Label Text="Increment/decrement: " VerticalTextAlignment="Center" />
        <Stepper Increment="1" Minimum="0" Maximum="1000" Value="{Binding CountValue, Mode=TwoWay}" />
      </StackLayout>
      <Button Text="Change font attributes" Command="{Binding ChangeFontAttributesCommand}" />
      <Button Text="Change badge color" Command="{Binding ChangeColorCommand}" />
      <Button Text="Change badge text color" Command="{Binding ChangeTextColorCommand}" HorizontalOptions="Center" />
      <StackLayout Orientation="Horizontal">
        <Label Text="Change font size: " VerticalTextAlignment="Center" />
        <Stepper Increment="1" Minimum="1" Maximum="100" Value="{Binding FontSize, Mode=TwoWay}" />
      </StackLayout>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

Step 4

We need to define the color and font for the badge, along with binding property value. Please follow the below code.

private static readonly List < Color > Colors = new List < Color > () {
    Color.Accent, Color.Aqua, Color.Black, Color.Blue,
        Color.Fuchsia, Color.Fuchsia, Color.Gray, Color.Green,
        Color.Lime, Color.Maroon, Color.Navy, Color.Pink,
        Color.Purple, Color.Red, Color.Silver, Color.Teal,
        Color.White, Color.Wheat, Color.WhiteSmoke
};
private static readonly List < FontAttributes > FontAttrs = new List < FontAttributes > () {
    FontAttributes.Bold, FontAttributes.Italic,
        FontAttributes.Bold | FontAttributes.Italic,
        FontAttributes.None
};
public Color BadgeColor {
    get;
    private set;
} = Color.Red;
public Color BadgeTextColor {
    get;
    private set;
} = Color.Black;

Step 5

We need to implement the command change event for changing the badge count values. Please follow the below code.

public ICommand ChangeColorCommand => new Command(obj => {
    _color++;
    if (_color >= Colors.Count) _color = 0;
    BadgeColor = Colors[_color];
    RaisePropertyChanged(nameof(BadgeColor));
});
public ICommand ChangeTextColorCommand => new Command(obj => {
    _textColor--;
    if (_textColor < 0) _textColor = Colors.Count - 1;
    BadgeTextColor = Colors[_textColor];
    RaisePropertyChanged(nameof(BadgeTextColor));
});
public ICommand ChangeFontAttributesCommand => new Command((obj) => {
    _fontIndex++;
    if (_fontIndex >= FontAttrs.Count) _fontIndex = 0;
    FontAttributes = FontAttrs[_fontIndex];
    RaisePropertyChanged(nameof(FontAttributes));
});

Step 6

Finally, please use the below full code for changing the badge count, color, font sizes, etc. It will help you to develop badges wherever you want to do so.

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace XamarinBadge {
    public class GenericBadgeTabViewModel: INotifyPropertyChanged {
        private static readonly List < Color > Colors = new List < Color > () {
            Color.Accent, Color.Aqua, Color.Black, Color.Blue,
                Color.Fuchsia, Color.Fuchsia, Color.Gray, Color.Green,
                Color.Lime, Color.Maroon, Color.Navy, Color.Pink,
                Color.Purple, Color.Red, Color.Silver, Color.Teal,
                Color.White, Color.Wheat, Color.WhiteSmoke
        };
        private static readonly List < FontAttributes > FontAttrs = new List < FontAttributes > () {
            FontAttributes.Bold, FontAttributes.Italic,
                FontAttributes.Bold | FontAttributes.Italic,
                FontAttributes.None
        };
        public Color BadgeColor {
            get;
            private set;
        } = Color.Red;
        public Color BadgeTextColor {
            get;
            private set;
        } = Color.Black;
        public ICommand ChangeColorCommand => new Command(obj => {
            _color++;
            if (_color >= Colors.Count) _color = 0;
            BadgeColor = Colors[_color];
            RaisePropertyChanged(nameof(BadgeColor));
        });
        public ICommand ChangeTextColorCommand => new Command(obj => {
            _textColor--;
            if (_textColor < 0) _textColor = Colors.Count - 1;
            BadgeTextColor = Colors[_textColor];
            RaisePropertyChanged(nameof(BadgeTextColor));
        });
        public ICommand ChangeFontAttributesCommand => new Command((obj) => {
            _fontIndex++;
            if (_fontIndex >= FontAttrs.Count) _fontIndex = 0;
            FontAttributes = FontAttrs[_fontIndex];
            RaisePropertyChanged(nameof(FontAttributes));
        });
        private int _color;
        private int _count = 1;
        private int _textColor;
        private int _fontIndex;
        private double _fontSize = (double) Plugin.Badge.Abstractions.Badge.BadgeFontSizeProperty.DefaultValue;
        public string Count => _count <= 0 ? string.Empty : _count.ToString();
        public int CountValue {
            get => _count;
            set {
                if (_count == value) return;
                _count = value;
                RaisePropertyChanged(nameof(CountValue));
                RaisePropertyChanged(nameof(Count));
            }
        }
        public FontAttributes FontAttributes {
            get;
            private set;
        } = FontAttributes.Bold;
        public double FontSize {
            get => _fontSize;
            set {
                if (_fontSize == value) return;
                _fontSize = value;
                RaisePropertyChanged(nameof(FontSize));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void RaisePropertyChanged(string propertyName) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Output

Conclusion

Hopefully, this article has given you sufficient information to create a Generic Badge control for both Android and iOS. Feel free to leave a comment if you would like me to further elaborate on anything within this article.