How to add tick marks on sliders in Xamarin Forms


Discrete sliders can use evenly spaced tick marks along the slider track, and the thumb will snap to them. Each tick mark should change the setting in increments that are discernible to the user.


However to achieve this in Xamarin Forms, one would have to add custom renderer in iOS and Android platforms, but here is a simple way of achieving it, without needing to add custom renderer. 


Step 1: Add a slider and a stack layout within  a grid.

<Grid Padding="0,0,0,0" WidthRequest="365">
<StackLayout WidthRequest ="364" x:Name="stack" ></StackLayout>
<Slider x:Name="slider" WidthRequest ="364"/>
</Grid> 
Step 2 : Declare constants 


private readonly int SliderMaxValue = 150;
private readonly int SliderMinValue = 0;
private readonly int SliderStepSize = 5;
private readonly int SliderTickWidth = 2;
private readonly int SliderTickHeight = 2;
Step 3 : Set slider Min and Max values

  slider.Maximum = SliderMaxValue;

  slider.Minimum = SliderMinValue;
Step 4:Set Stack view orientation  based on slider orientation.

           If the slider is horizontal add stack orientation horizontal.
           This stack view will contain the tick marks behind the slider.
   stack.Orientation = StackOrientation.Horizontal;
Step 5: Add the method to get the buffer offset based on thumb size and tick width.

private double GetOffsetFor(int index)
        {
            if (index == 0)
                return 0.0;
            else if (GetSeries().Contains(index))
                return 3.5;
            else
                return 2.5;
        }

        private int[] GetSeries()
        {
            int[] series = new int[13];
            int[] buffer = new[] {0, 0, 1, 1, 1, 2, 2, 1, 2, 3, 3, 3, 3};
            for (int i = 0; i <= 12; i++)
            {
                series[i] = 2 * i + buffer[i];
            }

            return series;
        }
Step 6: Add the ticks to the stack view 

public void AddTickMarksForSlider( StackLayout view)
        {
            int ticksDivider = SliderStepSize;
            int ticks = (int)slider.Maximum / ticksDivider;
          
            view.BackgroundColor = Color.Transparent;
         
            // make a UIImageView with tick for each tick in the slider
            for (int i = 0; i <= ticks; i++)
            {

                Label tick = new Label();
                tick.WidthRequest = SliderTickWidth;
                tick.HeightRequest = SliderTickHeight;

                view.Padding = new Thickness(15,0,14,0);

                tick.Margin = new Thickness(GetOffsetFor(i),0,0,0);

                tick.BackgroundColor =Color.Red;

                view.Children.Add(tick);

            }
        }


Step 7 : Make the slider steps discrete.

slider.ValueChanged += (sender, e) =>
            {
                double StepValue = SliderStepSize;

                var newStep = Math.Round(e.NewValue / StepValue);

                slider.Value = newStep * StepValue;
            };
This is how its going to look at the end.



I hope you enjoyed this blog... Please feel free to download the sample project from here

1 comment:

Popular Posts