0

I'm trying to create a custom slider in Xamarin.Forms, I have created a custom renderer for this purpose

protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Slider> e)
{
    base.OnElementChanged(e);
    if (e.NewElement != null)
    {
        // Set custom drawable resource
        Control.SplitTrack = false;
        Control.SetProgressDrawableTiled(
        Resources.GetDrawable(
        Resource.Drawable.custom_progressbar_style,
        (this.Context).Theme));

        Control.SetThumb(Resources.GetDrawable(
        Resource.Drawable.custom_thumb,
        (this.Context).Theme));
                        // Control.Bottom = 30;
    }
}

Here I'm loading two xml files one for progress bar and the other one is for slider's thumb. Progress bar is loaded from custom_progressbar_style and Thumb is being loaded from custom_thumb both of them are placed under Resource/drawable.

Progress bar xml content:

<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <item android:id="@android:id/background" android:height="10dp">
    <shape>
      <corners android:radius="3dp"/>
    </shape>
  </item>

  <item android:id="@android:id/secondaryProgress" android:height="10dp">
    <clip>
      <shape>
        <corners android:radius="3dp"/>
      </shape>
    </clip>
  </item>

  <item android:id="@android:id/progress" android:height="10dp">
    <clip>
      <shape>
        <corners android:radius="3dp"/>

      </shape>
    </clip>
  </item>

</layer-list>

Thumb xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:layout_gravity="center_vertical">
<!-- Larger white circle in back -->
<item  >
    <shape android:shape="oval">
        <solid android:color="#f0f0f0"/>
        <size
                android:width="30dp"
                android:height="30dp"/>
    </shape>
</item>
<!-- Smaller blue circle in front -->
<item>
    <shape android:shape="oval">
        <!-- transparent stroke = larger_circle_size - smaller_circle_size -->
        <stroke android:color="@android:color/transparent"
                android:width="10dp"/>
        <solid android:color="#6766f6"/>
        <size
                android:width="15dp"
                android:height="15dp"/>
    </shape>
</item>
</layer-list>

I have fixed the height of my custom slider to 10dp which is causing alignment issues with the slider's thumb. Can you suggest how I can overcome this alignment issue.enter image description here

Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29

1 Answers1

1

According to your description, I test your code and modify your custom_progressbar_style.xml, and I have on problem.

This is my custom_progressbar_style.xml, please take a look:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

 <item android:id="@android:id/background">
<shape>
  <corners android:radius="15dip" />
  <gradient
   android:startColor="#d9d9d9"
   android:centerColor="#e6e6e6"
   android:endColor="#d9d9d9"
   android:centerY="0.50"
   android:angle="270" />
  </shape>
 </item>

 <item android:id="@android:id/secondaryProgress">
<clip>
  <shape>
    <corners android:radius="15dip" />
    <gradient
         android:startColor="#e6b3e6"
         android:centerColor="#ffcce0"
         android:endColor="#e6b3e6"
         android:centerY="0.50"
         android:angle="270" />
  </shape>
</clip>
</item>

 <item android:id="@android:id/progress">
<clip>
  <shape>
    <corners android:radius="15dip" />
    <gradient
     android:startColor="#ff0066"
     android:centerColor="#ff00ff"
     android:centerY="0.50"
     android:endColor="#cc0052"
     android:angle="270" />
  </shape>
</clip>
 </item>

 </layer-list>

enter image description here

Update:

  <StackLayout>
        <local:customslider HeightRequest="10" VerticalOptions="CenterAndExpand" />
    </StackLayout>

Update again:

protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);        

        if (Control == null)
            return;

        SeekBar seekbar = Control;

        Drawable thumb = seekbar.Thumb;          
        thumb.SetBounds(thumb.Bounds.Left, -4, thumb.Bounds.Left + thumb.IntrinsicWidth,  thumb.IntrinsicHeight-4);
    }

enter image description here

Cherry Bu - MSFT
  • 10,160
  • 1
  • 10
  • 16
  • In your version of `custom_progressbar_style .xml` you have removed the height which I gave on my version of `custom_progressbar_style .xml`, The reason I'm giving this height explicitly is to make the height of the slider even across screens of different screen resolutions. – Shekher Khare May 29 '20 at 03:35
  • @ShekherKhare You can set height when you use it, please see my update. – Cherry Bu - MSFT May 29 '20 at 05:33
  • @CherryBUMSFT Yes, your xml creates similar UI as shown in your GIF, but if you see the image I posted, It has a circular thumb which should be vertically centred w.r.t progress bar and it's thumb should expand beyond the height of progress bar as shown in the image. I really appreciate your comments though :) – Shekher Khare May 29 '20 at 05:56
  • @ShekherKhareSh I use your custom_progressbar_style.xml, and I get the result that don't like you, please see my update screenshot. – Cherry Bu - MSFT May 29 '20 at 06:18
  • @CherryBuMSFT Yes, your image is looking correct but if you see the thumb, it's aligned towards bottom. It should be centred. Also, your emulator must an `xxhdpi` or `xxxhdpi`. mine is `hdpi`. I'm more focused on `hdpi` because the device where I need to deploy the app is an `hdpi (800 X 480)` device. I have upvoted your answer though. Thanks for your valuable time/effort. – Shekher Khare May 29 '20 at 10:05
  • @ShekherKhare Maybe you can override OnLayout method to change thumb position, please see my update. – Cherry Bu - MSFT Jun 02 '20 at 06:43