How to create sliding rating bar with half stars in NET MAUI

495 Views Asked by At

I managed to create a rating control for only displaying rate results, but I am struggling to come up with a solution as to where a user would slide the rating bar with stars and based on the sliding position the stars could fill either half-way or fully, the control would also return the value of the user input. Any tips or suggestions would be helpful, I tried creating a Horizontal Stack Layout, but I am not sure how to dynamically change the photos when sliding for example detect that the photo should be a half star. Attached image for the expected result below. It should work for Android and iOS.

enter image description here

3

There are 3 best solutions below

1
Liqun Shen-MSFT On BEST ANSWER

You could try using SkiaRate. See clovisnicolas/SkiaRate on Github.

Simply use the following code:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         ...
         xmlns:skia="clr-namespace:SkiaRate;assembly=SkiaRate.Forms">
    ...
    <skia:RatingView x:Name="myrate"  ColorOn="Yellow" Count="5"  PaintSurface="myrate_PaintSurface" />

In .cs file, get the score

    void myrate_PaintSurface(System.Object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
    {
        var a = myrate.Value;
        Console.WriteLine(myrate.Value);
    }

Hope it works for you.

2
FreakyAli On

You can checkout this control by Sebastian : https://medium.com/@tsjdevapps/net-maui-create-a-simple-rating-control-560566fa5014

It's Github: https://github.com/tsjdev-apps/maui-ratingcontrol

And you can use it as so:

        <controls:SimpleRatingControl Amount="5"
                                  CurrentValue="1"
                                  AccentColor="Black"
                                  StarSize="36" />
0
Andrew On

So I did this using a slider and a grid.

In my XAML:

<VerticalStackLayout
        Spacing="25"
        Padding="30,0"
        VerticalOptions="Center">

        <Grid
            x:Name="starGrid"
            ColumnDefinitions="*,*,*,*,*"  />

        <Slider MaximumTrackColor="Black"
                MinimumTrackColor="Black"
                Minimum="0.0"
                Maximum="5.0"
                ValueChanged="Slider_ValueChanged" />

</VerticalStackLayout>

I'm defining a grid that will hold my stars, and a slider that I'm going to listen to ValueChanged event when the user slides.

In the code behind:

void Slider_ValueChanged(Object sender, ValueChangedEventArgs e)
{
    starGrid.Children.Clear();

    if (e.NewValue >= .25 && e.NewValue < .75)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("half_star.png") }, 0,0);
    }
    else if (e.NewValue >= .75 && e.NewValue < 1.25)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 0,0);
    }
    else if (e.NewValue >= 1.25 && e.NewValue < 1.75)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 0, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("half_star.png") }, 1, 0);
    }
    else if (e.NewValue >= 1.75 && e.NewValue < 2.25)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 0, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 1, 0);
    }
    else if (e.NewValue >= 2.25 && e.NewValue < 2.75)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 0, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 1, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("half_star.png") }, 2, 0);
    }
    else if (e.NewValue >= 2.75)
    {
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 0, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 1, 0);
        starGrid.Add(new Image { Source = ImageSource.FromFile("star.png") }, 2, 0);
    }
}

Everytime the slider value changes, we clear the starGrid, then add the appropriate stars depending on the value. I stopped at three stars, but the pattern should be apparent.

Please note that this is not the most performant way to do this. Ideally, you wouldn't clear the grid with each value change, only when you need to update the stars. Also, the if statement is pretty ugly and could be greatly cleaned up. But this should be a good starting point.

enter image description here

enter image description here