Desenvolvimento

4 fev, 2019

O X do Xamarin Forms – Rating bar

Publicidade

Fala, galera! Tudobem?

Quantas estrelas você daria para esse artigo? hahaha

Existem muitos apps que precisam utilizar a famosa rating bar, seja para dar nota no próprio app ou para alguma funcionalidade especifica. Mas como implementar uma em Xamarin.Forms? Bem, você precisa criar o controle e um custom renderer por plataforma, já que cada uma possui a RatingBar de forma nativa.

Mas seguindo uma dica que vi em uma comunidade de Xamarin (do grande Altevir C. Neto ViCo), eu conheci um controle que implementa nossa necessidade! Então, depois de utilizar em um projeto na empresa, eu lhes apresento o Forms.Controls, que além de outros controles, possui a RatingBar.

Vamos ver como funciona?

Configurando o controle

Vamos ao bom e velho nuget baixar o controle Messier16.Forms.Controls e instalar em todos os nossos projetos:

Perfeito! Agora, tanto no iOS como no Android devemos inicializar o componente Messier16.Forms.iOS.Controls.Messier16Controls.InitAll();

iOS Appdelegate.cs:

 public override bool FinishedLaunching(UIApplication app, NSDictionary options)
 {
     global::Xamarin.Forms.Forms.Init();
     Messier16.Forms.iOS.Controls.Messier16Controls.InitAll();
     LoadApplication(new App());

     return base.FinishedLaunching(app, options);
 }

Android MainActivity.cs:

protected override void OnCreate(Bundle savedInstanceState)
{
   TabLayoutResource = Resource.Layout.Tabbar;
   ToolbarResource = Resource.Layout.Toolbar;

   base.OnCreate(savedInstanceState);
   global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
   Messier16.Forms.Android.Controls.Messier16Controls.InitAll();
   LoadApplication(new App());
}

Pronto! Vamos utilizar.

Utilizando o controle

Antes de mais nada, vamos adicionar no nosso projeto (utilizei o iOS como exemplo) as imagens que irão aparecer na nossa RatingBar. Você pode utilizar qualquer imagem, respeitando, claro, o tamanho de cada plataform:

Eu criei uma estrela vazia e uma preenchida para todos os tamanhos de tela do iOS.

Em nosso Xaml, temos que declarar o namespace : xmlns:messier16=”clr-namespace:Messier16.Forms.Controls;assembly=Messier16.Forms.Controls” e, em seguida, vamos implementar o controle com o exemplo abaixo:

<?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:messier16="clr-namespace:Messier16.Forms.Controls;assembly=Messier16.Forms.Controls"
             xmlns:local="clr-namespace:RatingBarExemplo" x:Class="RatingBarExemplo.MainPage" Padding="0,40,0,0">
    
    <StackLayout>
        <messier16:RatingBar FilledImage="star_filled.png" Image="star.png" MaxRating="10" FillColor="Navy" HeightRequest="50" />
    </StackLayout>
</ContentPage>

No controle podemos definir qual a imagem será a padrão da barra e qual deve aparecer ao selecionar. Além disso, o MaxRating diz qual vai ser o tamanho da nossa barra.

Vamos rodar:

Bem legal, né?! Podemos utilizar também as propriedades para obter os valores do controle em nossa ViewModel.

Vamos criar uma ViewModel simples:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace RatingBarExemplo
{
    public class MainViewModel : INotifyPropertyChanged
    {
        #region Property

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(storage, value))
            {
                return false;
            }

            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        #endregion

        private int _rating;
        public int Rating
        {
            get { return _rating; }
            set => SetProperty(ref _rating, value);
        }

      
    }
}

E, então, fazer o binding no controle:

<?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:messier16="clr-namespace:Messier16.Forms.Controls;assembly=Messier16.Forms.Controls"
             xmlns:local="clr-namespace:RatingBarExemplo" x:Class="RatingBarExemplo.MainPage" Padding="0,40,0,0">
    
    <StackLayout>
        <messier16:RatingBar FilledImage="star_filled.png" Image="star.png" MaxRating="10" FillColor="Navy" HeightRequest="50" />
        
         <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="3*"></ColumnDefinition>
                <ColumnDefinition Width="1*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>

            <messier16:RatingBar Rating="{Binding Rating, Mode=TwoWay}" FillColor="Maroon" FilledImage="star_filled.png" Image="star.png" MaxRating="5" HeightRequest="50" />
            <Label Text="{Binding Rating}" Grid.Column="1" Grid.Row="0" VerticalOptions="Center" HorizontalOptions="CenterAndExpand" HorizontalTextAlignment="Center"></Label>
            
       </Grid>
    </StackLayout>
</ContentPage>

Rodando:

iOS:

Android:

Esse controle é sensacional, não?!

Caso queira baixar o código utilizado no exemplo, clique aqui.

Espero ter ajudado e aquele abraço!