Create and display a badge on a page xamarin

1

I use xamarin.forms (Net Standard) and am having trouble creating a badge and displaying its value. I have a Tabbed Page that has a Grid with 8 cells.

Each cell has an image and each image will receive this badge with its respective value.

The page is below (xaml):

<Grid x:Name="grd" 
      RowSpacing="1" 
      ColumnSpacing="1" 
      Padding="0" 
      Margin="0" >
<Grid.RowDefinitions>
    <RowDefinition Height="1" />
    <RowDefinition Height="*" />
    <RowDefinition Height="*" />
    <RowDefinition Height="*" />
    <RowDefinition Height="*" />
    </Grid.RowDefinitions>
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

    <Image x:Name="imgDesvioFat" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" 
           Source="{local:ImageResource Operacional.Images.faturamento caixa-28.png}" 
           Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnDesvioFaturamentoTapReconizerTapped" 
                                  NumberOfTapsRequired="1">
            </TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>  
    <Image x:Name="imgTckCancelados" Grid.Row="1" Grid.Column="1" 
           Source="{local:ImageResource Operacinal.Images.tickets cancelados-05.png}" 
           Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnTckCanceladosTapGestureReconizerTapped" 
                                  NumberOfTapsRequired="1">
            </TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

    <Image x:Name="imgPrestacaoContas" Grid.Row="2" Grid.Column="0" Source="{local:ImageResource Operacional.Images.prestação de contas-07.png}" Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnPrestacaoContasTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

    <Image x:Name="imgArrecadacao" Grid.Row="2" Grid.Column="1" Source="{local:ImageResource Operacional.Images.pendencias de arrecadação-10.png}" Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnPendenciasTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

        <Image x:Name="imgOcupacao1" Grid.Row="3" Grid.Column="0" Source="{local:ImageResource Operacional.Images.ocupação maior 80-15.png}" Aspect="AspectFill" >
            <Image.GestureRecognizers>
                <TapGestureRecognizer Tapped="OnOcupacaoTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
            </Image.GestureRecognizers>
        </Image>

    <Image x:Name="imgOcupacao2" Grid.Row="3" Grid.Column="1" Source="{local:ImageResource Operacional.Images.ocupação menor 60-16.png}" Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnOcupacaoTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

    <Image x:Name="imgCheckList" Grid.Row="4" Grid.Column="0" Source="{local:ImageResource Operacional.Images.checklist-24.png}" Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnCheckListTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

    <Image x:Name="MyImage" Grid.Row="4" Grid.Column="1" Source="{local:ImageResource Operacional.Images.mensagens-21.png}" Aspect="AspectFill">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnTrocaImageTapGestureReconizerTapped" NumberOfTapsRequired="1"></TapGestureRecognizer>
        </Image.GestureRecognizers>
    </Image>

    <AbsoluteLayout>
        <Label x:Name="lblFaturamento" Text="" AbsoluteLayout.LayoutBounds="20,8,40,100" Grid.Row="1" Grid.Column="0" TextColor="White" FontSize="9" FontAttributes="Bold"/>
        <Label x:Name="lblCancelados" Text=""  AbsoluteLayout.LayoutBounds="195,8,40,100" Grid.Row="1" Grid.Column="1" TextColor="White" FontSize="9" FontAttributes="Bold"/>
        <Label x:Name="lblPrestacaoContas" Text="" AbsoluteLayout.LayoutBounds="20,8,40,100" Grid.Row="2" Grid.Column="0" TextColor="White" FontSize="9" FontAttributes="Bold"/>
        <Label x:Name="lblPendencias" Text="" Grid.Row="2" Grid.Column="1" TextColor="White" FontSize="9" FontAttributes="Bold"/>
        <Label x:Name="lblOcupacao1" Text="" AbsoluteLayout.LayoutBounds="20,232,80,100" Grid.Row="3" Grid.Column="0" TextColor="White" FontSize="9" FontAttributes="Bold"/>
        <Label x:Name="lblOcupacao2" Text="" AbsoluteLayout.LayoutBounds="196,234,80,100" Grid.Row="3" Grid.Column="1" TextColor="White" FontSize="9" FontAttributes="Bold"/>
    </AbsoluteLayout>
</Grid>

This is the method I use to change the image and value of the label that should now be in the badge

var resultado = CalcularResultado(); // Código irrelevante

label.Text = resultado;

The variable that will receive the value to be printed on the badge is result . This is the code I got on the internet to create the badge ( CircleView ):

public partial class CircleView : BoxView
{
    public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(double), typeof(CircleView), 0.0);

    public double CornerRadius
    {
        get { return (double)GetValue(CornerRadiusProperty); }
        set { SetValue(CornerRadiusProperty, value); }
    }

    public CircleView()
    {
        InitializeComponent();
    }
}

// The renderer I created in the Droid project // Irrelevant code

The xaml of BadgeView :

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:local="clr-namespace:your_local_namespace"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"      
      x:Class="your_local_namespace.BadgeView"     
      HeightRequest="16"     
      WidthRequest="16">
    <local:CircleView x:Name="BadgeCircle" 
                      HeightRequest="16" 
                      WidthRequest="16" 
                      CornerRadius="16" 
                      VerticalOptions="Center" 
                      HorizontalOptions="Center" />
    <Label x:Name="BadgeLabel" 
           TextColor="White" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" 
           VerticalTextAlignment="Center" 
           HorizontalTextAlignment="Center" 
           FontSize="10"/>
</Grid>

The codebehind of BadgeView :

public partial class BadgeView : Grid
{
    public static BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(BadgeView), "0", propertyChanged: (bindable, oldVal, newVal) =>
    {
        var view = (BadgeView)bindable;
        view.BadgeLabel.Text = (string)newVal;
    });

    public static BindableProperty BadgeColorProperty = BindableProperty.Create("BadgeColor", typeof(Color), typeof(BadgeView), Color.Blue, propertyChanged: (bindable, oldVal, newVal) =>
    {
        var view = (BadgeView)bindable;
        view.BadgeCircle.BackgroundColor = (Color)newVal;
    });

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public Color BadgeColor
    { 
        get { return (Color)GetValue(BadgeColorProperty); }
        set { SetValue(BadgeColorProperty, value); }
    }

    public BadgeView()
    {
        InitializeComponent();
        BadgeLabel.Text = Text;
        BadgeCircle.BackgroundColor = BadgeColor;
    }
}

Here it seems to be the call of the badge which should be from within the class that has the method to fill in the values.

<Grid>
    <Label HorizontalTextAlignment="Center" 
           Text="Look at me!"/>
    <views:BadgeView Text="3" 
                     BadgeColor="Green" 
                     VerticalOptions="Start" 
                     HorizontalOptions="End"/>
</Grid>
    
asked by anonymous 23.02.2018 / 15:46

1 answer

2

Two components are actually being created.

The first of these is CircleView for which you need a renderer on the platform. The second is BadgeView - again - is not a page is just a component, a View ( Grid ) with the other view you created CircleView and a label about it.

The last code in your question shows how you will use it in XAML, assigning a color (Green) to a value (3) for the badge.

In your case, to use it on the images of your page, just follow the example below. After declaring Image , declare a badge in the same column and grid line:

<Image x:Name="imgDesvioFat" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" 
       Source="{local:ImageResource Operacional.Images.faturamento caixa-28.png}" 
       Aspect="AspectFill">
    <Image.GestureRecognizers>
        <TapGestureRecognizer Tapped="OnDesvioFaturamentoTapReconizerTapped" 
                              NumberOfTapsRequired="1">
        </TapGestureRecognizer>
    </Image.GestureRecognizers>
</Image>

<BadgeView Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
           x:Name="bdgDesvioFat"
           BadgeColor="Red"/>

And there where you assign the value of the label ( label.Text = resultado ) you would assign the text to the corresponding badge: bdgDesvioFat.Text = resultado; .

Suggestion:

If you were using bindings you would have a reduction of at least 40% of that whole code being written. In addition to being clearer, it reduces error points and facilitates the application of automated tests. It's a good search

    
23.02.2018 / 16:37