Jasmin Sojitra
Jasmin Sojitra

Reputation: 1301

How to create below type of custom progress bar in xamarin forms

How To develop this type of Design(I have attached image below)

enter image description here

Upvotes: 0

Views: 1337

Answers (1)

Paul Kertscher
Paul Kertscher

Reputation: 9713

Supposedly you are referring to the bars, not the overall layout, but it's not 100% clear from your question. While there are other possibilities to display the bars, I achieved quite a satisfying result by nesting an AbsoluteLayout in a frame. See the following example for one of the bars on the right

<Frame HasShadow="False" HeightRequest="20" CornerRadius="5" HorizontalOptions="Fill" Padding="0" BackgroundColor="Silver" IsClippedToBounds="True">
    <AbsoluteLayout>
        <ContentView AbsoluteLayout.LayoutFlags="All" 
                     AbsoluteLayout.LayoutBounds="0,0,.33,1" 
                     BackgroundColor="CadetBlue">
            <Label Text="33%" 
                   FontSize="Small" 
                   HorizontalOptions="Center" 
                   VerticalOptions="Center" 
                   TextColor="White" 
                   FontAttributes="Bold" />
        </ContentView>
    </AbsoluteLayout>
</Frame>

The bar itself is wrapped by a Frame to get the rounded corners (see the CornerRadius property). Setting IsClippedToBounds to true is necessary, because otherwise the children won't be clipped and the rounded corners do not show.

Within the Frame there is the AbsoluteLayout the actual bars are placed in. And within, I added the dark-greenish bar as a ContentView (to be able to add a label with the percentage).

Please see the following code for one of the green/red bars. Basically it's the same, but I added two sub-bars within the absolute layout

<Frame HasShadow="False" HeightRequest="20" CornerRadius="5" HorizontalOptions="Fill" Padding="0" BackgroundColor="Silver" IsClippedToBounds="True">
    <AbsoluteLayout>
        <ContentView AbsoluteLayout.LayoutFlags="All" 
                     AbsoluteLayout.LayoutBounds="0,0,.25,1"
                     BackgroundColor="LimeGreen">
            <Label Text="25%" 
                   FontSize="Small"  
                   HorizontalOptions="Center" 
                   VerticalOptions="Center" 
                   TextColor="White" 
                   FontAttributes="Bold" />
        </ContentView>
        <ContentView AbsoluteLayout.LayoutFlags="All" 
                     AbsoluteLayout.LayoutBounds="1,0,.75,1"
                     BackgroundColor="Red">
            <Label Text="75%" 
                   FontSize="Small" 
                   HorizontalOptions="Center" 
                   VerticalOptions="Center" 
                   TextColor="White" 
                   FontAttributes="Bold" />
        </ContentView>
    </AbsoluteLayout>
</Frame>

Generalization

It'd be useful to extract a re-usable component. I will show for the simpler bar. Transferring the solution to the more complex one should be easy, though.

Code behind

In the code behind the following properties have to be added

public Rectangle FirstBarBounds => new Rectangle(0, 0, BarValue, 1);

public double BarValue
{
    get => this._barValue;
    set
    {
        if (this._barValue == value)
        {
            return;
        }

        this._barValue = value;
        this.OnPropertyChanged();
    }
}

(Adding a BindableProperty for BarValue could be useful, too, but admittedly I was too lazy.)

The properties can be bound to from XAML

<Frame ...>
    <AbsoluteLayout>
        <ContentView AbsoluteLayout.LayoutFlags="All" 
                     AbsoluteLayout.LayoutBounds="{Binding FirstBarBounds}"
                     BackgroundColor="CadetBlue" >
            <Label Text="{Binding FirstBarValue, StringFormat='{}{0:P0}'}" 
                   FontSize="Small" 
                   HorizontalOptions="Center" 
                   VerticalOptions="Center" 
                   TextColor="White" 
                   FontAttributes="Bold" />
        </ContentView>
    </AbsoluteLayout>
</Frame>

The LayoutBounds of the ContentView is bound to BarBounds (which in turn uses BarValue to determine the bounds of the bar) and the text is bound to BarValue. Since BarValue is a double, the value is formatted to a percentage by StringFormat='{}{0:P0}'.

Screenshot

Please see the following screen shot on how the bars are rendered on an Android device (Emulator).

Image displaying the bars

Upvotes: 4

Related Questions