Changing a slider control’s thumb skin

by Peter deHaan on September 12, 2007

The following example shows how you can customize a slider control (HSlider or VSlider) and use your own custom embedded image instead of the default triangle thumb skin.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/09/12/changing-a-slider-controls-thumb-skin/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Style>
        ToolTip {
            backgroundAlpha: 1.0;
            backgroundColor: haloBlue;
            fontWeight: bold;
            color: white;
        }

        HSlider {
            thumbSkin: Embed(source="assets/bug.png");
            dataTipPlacement: right;
            dataTipOffset: 0;
        }
    </mx:Style>

    <mx:HSlider id="slider"
            minimum="-10"
            maximum="20"
            labels="[-10, 0, 10, 20]"
            snapInterval="1"
            tickInterval="10"
            liveDragging="true"
            dataTipPrecision="0"
            showTrackHighlight="true" />

</mx:Application>

View source is enabled in the following example.

If you wanted to change the width and height of the thumb within the Slider, you can do this by extending the SliderThumb class and setting the width and height properties from within the constructor. For example, create a new file named “BigThumbClass.as” and save it in the same directory as your MXML file. Enter the following code into the BigThumbClass class:

package {
    import mx.controls.sliderClasses.SliderThumb;

    public class BigThumbClass extends SliderThumb {
        public function BigThumbClass() {
            super();
            this.width = 16;
            this.height = 16;
        }
    }
}

Now, in your MXML file, set the sliderThumbClass property to your custom BigThumbClass class, as seen in the following snippet:

<mx:HSlider id="slider"
        minimum="-10"
        maximum="20"
        labels="[-10, 0, 10, 20]"
        snapInterval="1"
        tickInterval="10"
        liveDragging="true"
        dataTipPrecision="0"
        showTrackHighlight="true"
        sliderThumbClass="BigThumbClass" />

View source is enabled in the following example.

{ 46 comments… read them below or add one }

Mike September 13, 2007 at 1:07 pm

Great article. Do you know of any way to apply different skins for sliders with multiple thumbs?

Reply

peterd September 13, 2007 at 1:30 pm

Mike,

Try something like the following:

<mx:Script>
    <![CDATA[
        import mx.controls.sliderClasses.SliderThumb;

        [Embed(source="assets/bullet_add.png")]
        private var BulletAdd:Class;

        [Embed(source="assets/bullet_delete.png")]
        private var BulletDelete:Class;

        private function initThumbs():void {
            var thumb1:SliderThumb = slider.getThumbAt(0);
            thumb1.setStyle("thumbSkin", BulletAdd);

            var thumb2:SliderThumb = slider.getThumbAt(1);
            thumb2.setStyle("thumbSkin", BulletDelete);
        }
    ]]>
</mx:Script>

<mx:HSlider id="slider"
        minimum="-10"
        maximum="20"
        labels="[-10, 0, 10, 20]"
        snapInterval="1"
        tickInterval="10"
        liveDragging="true"
        dataTipPrecision="0"
        showTrackHighlight="true"
        thumbCount="2"
        values="[2,8]"
        creationComplete="initThumbs()" />

Reply

Mike September 13, 2007 at 2:41 pm

Hi Peter,

Brilliant. Thanks for the tip.

Only one issue I had was with setting “thumbSkin”. Looks like the version of flex I’m using doesn’t support that. I have to explicitly set the thumbUpSkin, thumbDownSkin, etc. I’m using flex Builder Version: 2.0.155577.

Regards,
Mike

Reply

peterd September 13, 2007 at 3:01 pm

Yeah, sorry, I’m using Flex 3 beta so there may be some occasional differences like this. I usually don’t do a lot of backwards compatibility testing to make sure the examples work in earlier versions of the Flex SDK, so if you catch any other “gotchas” like that, note them in the comments. :)

BFF,
Peter

Reply

Mike September 13, 2007 at 11:10 pm

I’m trying to annotate video cue points using multiple thumbs on a slider. Works well but I’ve not figured out how to dynamically generate a new thumb and add it to the slider. Is there a simpler way or a better approach to doing something like this?

Thanks,
Mike

Reply

peterd September 13, 2007 at 11:21 pm

Mike,

The above post only really addresses skinning an existing thumb skin, not adding new thumbs dynamically.

Does that following snippet get you any closer?

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle">

    <mx:Script>
        <![CDATA[
            private function addThumb():void {
                slider.thumbCount = slider.thumbCount \+ 1;
                var slVal:Array = slider.values;
                slVal.push(slider.thumbCount);
                slider.values = slVal;
            }
        ]]>
    </mx:Script>

    <mx:Button label="add thumb" click="addThumb()" />

    <mx:HSlider id="slider" allowThumbOverlap="true" />

</mx:Application>

Basically whenever you click the Button control, a new thumb is added (setting thumbCount \+=1). Then I assign the new slider thumb’s value by pushing a new value onto the “values” property. You’d want to clean that code up a bit. I just set the newest value to the thumb count, but its a bit clumsy.

Hope that helps,
Peter

Reply

Mike September 14, 2007 at 8:31 am

Hi Peter,

Works like a champ. You have been a great help. I was stuck on adding the new thumb, thinking I needed to instantiate a new sliderThumb object and add it to the slider. Looks like this get done for you simply by updating the thumbCount.

Thanks a million,
Mike

Reply

Leon September 20, 2007 at 10:18 pm

Great article,

I think i have found why flex builder 2 cannot display the custom skin correctly.

It seems that we should define the following attributes in flex builder 2

thumbUpSkin:Embed(source="assets/bug.png");
thumbOverSkin:Embed(source="assets/bug.png");
thumbDownSkin:Embed(source="assets/bug.png");

Reply

Ronzoni November 29, 2007 at 8:42 pm

I needed to change the thumbSkin with each thumb potentially different sizes.
To prevent it from scaling I made this class:

package player.gui.slider {
	import mx.controls.sliderClasses.SliderThumb;

	public class MySliderThumb extends SliderThumb {
		public function MySliderThumb() {
			super();
		}

		override protected function measure():void {
			super.measure();
			measuredHeight = minHeight;
			measuredWidth = minWidth;
		}
	}
}

Not sure if that’s potentially problematic, or if there is any easier way to do that..

Anyone know how I can make my thumb not overlap over the ends of the track (and still report the correct value)?

Reply

Ronzoni November 30, 2007 at 2:12 pm

I have two questions:

1) How can I make my thumb not overlap the ends of the track?
I haven’t even attempted this yet, too busy with other bugs, but it seems like it’s something that should be fairly desirable.

2) I would like the measuredHeight of my slider to be only the track height. I can’t seem to access the track though in anyway..I’ve been trying very hard..

Reply

jack December 6, 2007 at 6:33 am

Hi,
This is a big help. I tried it and have one serious problem. I’m emulating a scrollbar, but want the control of hslider. So the thumb is a rather large shape, 240 pixels. I’m using a skin for the track as well, and for some reason it’s leaving big gaps in the track when I use the thumbclass setting such a big width.

Do you have any ideas?

Thanks

Reply

john December 24, 2007 at 9:07 am

Hi,
Thanks for your article.
I have one question:
like below:

HSlider {
            thumbSkin: Embed(source="assets/bug.png");
            dataTipPlacement: right;
            dataTipOffset: 0;
        }

I wan’t dynamic change the thumbSkin by coding.How can I code?

Reply

peterd January 8, 2008 at 3:40 pm

john,

Something like the following should work:

<?xml version="1.0" encoding="utf-8"?>
<!-- main.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="top"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            [Bindable]
            [Embed(source="add.png")]
            private var icon1:Class;

            [Bindable]
            [Embed(source="delete.png")]
            private var icon2:Class;

            private function style1():void {
                /* Short */
                StyleManager.getStyleDeclaration("HSlider").setStyle("thumbSkin", icon1);
            }

            private function style2():void {
                /* Long */
                var cssObj:CSSStyleDeclaration = StyleManager.getStyleDeclaration("HSlider");
                cssObj.setStyle("thumbSkin", icon2);
            }
        ]]>
    </mx:Script>

    <mx:Style>
        HSlider {
            thumbSkin: Embed(source="add.png");
            dataTipPlacement: right;
            dataTipOffset: 0;
        }
    </mx:Style>

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="icon 1" icon="{icon1}" click="style1();" />
        <mx:Button label="icon 2" icon="{icon2}" click="style2();" />
    </mx:ApplicationControlBar>

    <mx:HSlider id="slider" sliderThumbClass="BulletThumbClass" />

</mx:Application>
/** BulletThumbClass.as */
package {
    import mx.controls.sliderClasses.SliderThumb;

    public class BulletThumbClass extends SliderThumb {
        public function BulletThumbClass() {
            super();
        }

        override protected function measure():void {
            super.measure();
            measuredHeight = minHeight;
            measuredWidth = minWidth;
        }
    }
}

Hope that helps,
Peter

PS: Thanks to Ronzoni’s comments above for the measure() trick so you don’t have to hard-code icon dimensions.

Reply

jeffs January 22, 2008 at 12:02 pm

Is it possible to use a UIComponent as a skin for say the thumbUpSkin. How would I go about assigning that to the hSlider?

Reply

Anand Jha March 8, 2008 at 2:36 am

Hi Peter

Please help me in achieving the following:

“To drag the region between the thumbs, if the HSlider has two thumbs”.

Do we have any option in HSlider?

Or

Do i need to rewrite HSlider which will implement Slider?

Thanx in advance

~Anand

Reply

peterd March 8, 2008 at 10:18 am

Anand,

Something like Doug McCune’s Draggable Slider Component for Flex?

Peter

Reply

JOse May 20, 2008 at 1:19 pm

Hi Peter,

This is a big help. Thanks. You have been a great help. I´m from Uruguay and I needed use sliders from make a zoom in a column chart.

Do you have any ideas?

Thanks

Reply

carlo de marchis November 27, 2008 at 8:35 am

Is it possible to skin different thumbs with different colors?
i.e. one slider has 4 thumbs each of a different color to indicate different objects?

Reply

NITIN December 9, 2008 at 10:49 pm

Hi, gr8 discussion.

I am having problem in highlighting a track.
when we set showTrackHighlight="true" then only the track portion on left of thumb is painted.
how can I highlight right portion of a track i.e. rest of the track.

I want to paint track portion in two colors.

Do any one have any ideas?

Thanks.

Reply

adekunle December 11, 2008 at 12:56 am

i couldn’t change my thumb. when i used the code above, i was getting this error message “cannot resolve attribute thumbskin for component type mx.controls.HSlider”. I’m using Adobe flex 2. I will appreciate your quick response.

Reply

flexBeginner February 25, 2009 at 7:25 am

Why can’t you specify the thumbSkin image source in the constructor of the BigThumbClass? Wouldn’t that make more sense?

Reply

stoimen March 25, 2009 at 3:41 am

Actually I couldn’t manage to make it work with the sliderThumbClass="BigThumbClass" with the given error of something like “the definition of BigThumbClass cannot be found”, until I put brackets around it: sliderThumbClass="{BigThumbClass}".

greetings

Reply

Guru April 2, 2009 at 11:49 pm

When using multiple thumbs, only the first two thumbs are highlighted(color filled with first two thumbs). Is it possible to fill color for other pair of thumbs.

your help is highly important.

thanks
Guru

Reply

avn.rocky April 14, 2009 at 6:05 am

Hi Friends!
first of all I would like to say thanks for this post.

Please help me out, I just want to change the bars below slider.
I have designed gradients in my UI but I am unable to customize the bars below slider.

avn

Reply

sami June 22, 2009 at 12:22 pm

Hi Peter

Thanks for the great tutorials… I have been looking all over for this but cannot find it – is there a way to set the slider thickness? I know we can set it for the tick but for the slider itself??

Thanks

- Sami

Reply

Peter deHaan June 22, 2009 at 6:05 pm

sami,

I don’t think so. I’d probably just create a custom thumb skin that is whatever size you want and use that instead.

Peter

Reply

sami June 26, 2009 at 3:20 am

Hi Peter

Thanks for that – I tried setting a jpg skin for the “trackSkin” property and it worked… though it’s a bit tricky

BR
- Sami

Reply

Anurag Chouksey July 11, 2009 at 6:39 am

Hello Peter,

I have to show tooltip for the hslider on rollover of the slider icon..

Can u please help me with that .Is there any such method.

Regards
Anurag

Reply

yuva August 3, 2009 at 11:36 pm

Hi,

I have created hslider with some reference site. I need to fire the event of thumbSkin change movement to function sliderChange. I have got value doesn’t macth for requirement. And also didn’t get the proper Currrent Slider value for checking for my requirement. Please any body help with this point.

       private function sliderChange(event:SliderEvent):void {
              Alert.show("Slider Value"+(Slider(event.currentTarget)));           
              var currentSlider:Slider=Slider(event.currentTarget);
              txt.text="{Math.round(currentSlider.value)}";
              var val:Number = Math.round(currentSlider.value);
 
               if(val &lt; 50)
                {
                 theme.visible = true; 
                 themes.visible = false;
                }
                else
                {
                  themes.visible = true;
                    theme.visible = false; 
                }
      }

Regards
yuva

Reply

aquarian August 29, 2009 at 11:16 am

is there any way we can display the current value of slider on thumb ??

Reply

justme October 22, 2009 at 5:21 am

Hi all,

is it possible to create a non-stretchy thumbIcon on a slider or scrollbar? I’m trying to create a custom scrollbar. I’m only using a simple trackSkin with a small, circular (15px by 15px) thumbIcon. I’ve tried a lot of things to get this working, but nothing seems to be working. At this moment I’ve a .png with transparency to the background, and de scaleGridTop and bottom set to the last pixel of the image. This keeps the thumbIcon intact, but it creates a big kind of ‘margin’ (in fact its a largely stretched 1px transparent part of the png). Is there some sort of option that says ‘unscaledThumbIcon = true’ or anything like it… (Sorry, I’m a noob)

Greetz and thanx in advance!

Reply

Fesko December 9, 2009 at 6:01 pm

Anyway to make the slider verticle? Can some one help?

Reply

Peter deHaan December 10, 2009 at 6:46 am

@Fesko,

Use a VSlider instead of an HSlider.

Peter

Reply

Omer December 18, 2009 at 11:05 pm

Is there a way to change the track height? like this http://www.box.net/shared/efai651ob6

Reply

ATD January 7, 2010 at 12:33 am

This was a great help!

Do you know of a way to assign colors to each thumb from the flex colorpicker? Since there are a LOT of colors to choose from, I can’t just swap out icons for the thumb.

Reply

Peter deHaan January 7, 2010 at 12:45 pm

@ATD,

You can change thumb colors by using the getThumbAt() method:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                horizontalAlign="left">
 
    <mx:Script>
        <![CDATA[
            protected function sl_creationCompleteHandler():void {
                sl.getThumbAt(0).setStyle("fillColors", ["red", "red"]);
                sl.getThumbAt(0).setStyle("themeColor", "red");
                sl.getThumbAt(1).setStyle("fillColors", ["haloGreen", "haloGreen"]);
                sl.getThumbAt(1).setStyle("themeColor", "haloGreen");
            }
        ]]>
    </mx:Script>
 
    <mx:ApplicationControlBar dock="true">
        <mx:Label id="sdkVer" initialize="sdkVer.text = mx_internal::VERSION;" />
    </mx:ApplicationControlBar>
 
    <mx:HSlider id="sl"
                thumbCount="2"
                allowThumbOverlap="true"
                creationComplete="sl_creationCompleteHandler();" />
 
</mx:Application>

Peter

Reply

Zitchdog January 11, 2010 at 6:45 pm

Hi Peter and the FE community. First I want to thank you for this wonderfull site. You’re helping a lot of people man. I hope we could give back someday.

Here’s my question.
When I set two differents skins for a thumb (for instance one for the upSkin and one for the overSkin), it seems that only the upSkin has the custom size. When I point the thumb with the mouse it goes back to the default size. Do you think we need to override another method to get this problem solved ?

My code is the same than yours except in the css where I have a skin for each thumb state.

Reply

jacsdev April 9, 2010 at 2:11 pm

hi, incredible article, i mean, it’s clear, it’s easy… 100 points!!…
i recommended your web page in twitter (http://blog.flexexamples.com)..

Reply

np May 27, 2010 at 12:00 pm

Hi, this article is great! But i can’t still figure out one thing. I would like to position some of the thumbs a bit lower than others (below tracker line). Is this possible? Or should I emulate this by creating “special” images?

Reply

Peter deHaan May 27, 2010 at 12:11 pm

@np,

I believe you can tweak the thumbOffset style. I thought I had an example of this on my blog, but I cannot find it so I’ll try and post a simple example shortly.

<mx:HSlider id="sl" thumbOffset="{sl.value}" liveDragging="true" />

Peter

Reply

Peter deHaan May 27, 2010 at 12:38 pm
np May 28, 2010 at 5:29 am

Tkank you very much. Works like a charm :) But what if I need to position one (or few – but not all) of the thumbs a little bit higher than the others? I tried to change thubm y property but it doesn’t help.

Peter deHaan May 28, 2010 at 7:03 am

@np,

This works for me in Flex 3.5 SDK. I had to use the updateComplete because when I tried setting the y property in the creationComplete event handler, the thumb offset would snap back to it’s original value after dragging the thumb:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Script>
        <![CDATA[
            protected function setThumbY(evt:Event):void {
                sl.getThumbAt(1).y = 10;
            }
        ]]>
    </mx:Script>
 
    <mx:HSlider id="sl"
            thumbCount="2"
            values="[3,7]"
            showTrackHighlight="true"
            updateComplete="setThumbY(event);"/>
 
</mx:Application>

Peter

np May 29, 2010 at 12:38 am

That works great! Thank you very much :)

tsveti August 16, 2010 at 2:32 pm

Hi all,
I am really new to flex and I am trying to make a slider with animated thumb(i.e. I want to reload the thumb in few milliseconds so that it would look like animation). I used the example above to put a picture on the thumb but when I try to change it with setStyle method it’s not changing…If anyone can help…here’s my code:

….

….
public function MoveSheep():void
{
import mx.controls.sliderClasses.SliderThumb;
slidersheep.setStyle(“thumbSkin”, “{sec.source}”);
//Alert.show(“sheep”, slidersheep.getStyle(“thumbSkin.source”));
}

Alert is indicating the new source but visually, there is no change.
And one more question…if I try to declare picture “sec” in AS I constantly get the error “1114 public attribute can used in this package”.
I know that these are very stupid questions but I can’t fix them :)
tsveti

Reply

tsveti August 16, 2010 at 2:37 pm

&ltmx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” xmlns:player=”org.bytearray.gif.player.*”&gt
&ltmx:HSlider id=”slidersheep”
change=”MoveSheep()”
snapInterval=”0.5″
tickInterval=”10″
liveDragging=”true”
showTrackHighlight=”true”
sliderThumbClass=”BigThumbClass” width=”732″ height=”117″
thumbSkin=”@Embed(source=’first.png’)” y=”10″ /&gt

&ltmx:Image id=”sec” source=”second.png” x=”10″ y=”189″/&gt

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: