Flex Mobile Development – SpinnerList Sample (with source code)

November 14, 2011By 17 Comments

There was a lot of news from Adobe last week surrounding the Flash platform and Flex SDK (understatement :)!!) I know many have formed their own opinions on the state of affairs, but the bottom line is, we need to move forward now and be productive again. Flex 4.6 will launch soon and there are some really cool new components that I want to continue to highlight prior to the launch.

The next in my series is the new SpinnerList component. It can be used to show a list of items that appears to wrap around an animated spinner control. The list shows five items by default. If you want to change the default number of items shown, you can create a custom skin.

Here’s an example of the SpinnerList:

The sample code for the above View looks like the following:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" title="Sample SpinnerList" xmlns:r="renderers.*">
	
	<s:layout>
		<s:VerticalLayout paddingTop="40" paddingBottom="5" paddingLeft="5" paddingRight="5" gap="10" 
						  horizontalAlign="center" verticalAlign="top"/>
	</s:layout>
	
	<s:TextArea width="90%" editable="false" skinClass="spark.skins.mobile.TextAreaSkin"
				text="The SpinnerList control displays a list of items that wraps around an animated wheel. The item in the center is always the selected item. The list can be spun by upward and downward throws or by dragging up or down to select items or simply clicked to choose an item. You place this component in a SpinnerListContainer which provides the chrome and layout for it. The SpinnerListItemRenderer is the default item renderer which can also be overridden."/>	
	<s:Label text="Select a location..."/>
	<s:SpinnerListContainer width="200">
		<s:SpinnerList width="100%">
			<s:dataProvider>
				<s:ArrayCollection>
					<fx:String>Boston, MA</fx:String>
					<fx:String>Chicago, IL</fx:String>
					<fx:String>Honolulu, HI</fx:String>
					<fx:String>New York, NY</fx:String>
					<fx:String>San Francisco, CA</fx:String>
					<fx:String>San Jose, CA</fx:String>
					<fx:String>Washington, DC</fx:String>
				</s:ArrayCollection>
			</s:dataProvider>
		</s:SpinnerList>
	</s:SpinnerListContainer>	
</s:View>

List Data
The SpinnerList control takes anything implementing the IList interface for the dataProvider, so you could bind it to an ArrayCollection, ArrayList, NumericDataProvider, XMLListCollection etc. This next example shows how to bind to an ArrayCollection containing a complex object versus a simple String. You could use a similar approach for data coming back as complex objects from a service call stored in an ArrayCollection:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" title="Sample SpinnerList" xmlns:r="renderers.*">	
	<s:layout>
		<s:VerticalLayout paddingTop="40" paddingBottom="5" paddingLeft="5" paddingRight="5" gap="10" 
						  horizontalAlign="center" verticalAlign="top"/>
	</s:layout>
	<s:TextArea width="90%" editable="false" skinClass="spark.skins.mobile.TextAreaSkin"
				text="You can bind to data from a service result or externally defined list containing a complex object and refer to the String to be shown with the 
labelName property."/>
	
	<fx:Declarations>
		<s:ArrayCollection id="suppliesAC">
			<fx:Object name="Ink" price="54.99"/>
			<fx:Object name="Stapler" price="3.59"/>
			<fx:Object name="Printer" price="129.99"/>
			<fx:Object name="Notepad" price="2.49"/>
			<fx:Object name="Mouse" price="21.79"/>
			<fx:Object name="Keyboard" price="32.99"/>
		</s:ArrayCollection>
	</fx:Declarations>
	
	<s:Label text="Select Supply:"/>
	<s:SpinnerListContainer width="200">
		<s:SpinnerList id="supplyList" width="100%" labelField="name" dataProvider="{suppliesAC}"/>
	</s:SpinnerListContainer>	
		
	<s:Label text="Selected Supply: {supplyList.selectedItem.name} @ {supplyList.selectedItem.price}"/>
</s:View>

The above code produces the following:

SpinnerListContainer
Notice that the SpinnerList is put in a SpinnerListContainer which provides the chrome and a layout for it (HorizontalLayout by default). If you do not include the SpinnerList in a SpinnerListContainer, it would like the following (not very useful!):

If you plan to bind a couple of SpinnerList controls together, you can do this by putting them all within the same SpinnerListContainer and they will be horizontally laid out properly by default. The new Flex 4.6 DateSpinner control is an example of this… See below on ‘Selecting Items’ for another example of two SpinnerList‘s in one SpinnerListContainer.

List Wrapping
By default the list items wrap, however if you don’t want this to occur by default, you can set the wrapElements property to false and it will not wrap:

...
<s:SpinnerList id="list" width="100%" wrapElements="false">
...

You can see the empty item in the last spot in the following screenshot since the wrapElements is false:

Displaying the Label
You can use a labelFunction instead of a labelField for the label shown in the list. Here’s an example of using a simple labelFunction to concatenate the name and price properties from the data object:

...
<fx:Script>
	<![CDATA[
		protected function lblFunction(item:Object):String
		{
			return item.name + " @ " + item.price;
		}
	]]>      
</fx:Script>
...
         <fx:Declarations>
		<s:ArrayCollection id="suppliesAC">
			<fx:Object name="Ink" price="54.99"/>
			<fx:Object name="Stapler" price="3.59"/>
			<fx:Object name="Printer" price="129.99"/>
			<fx:Object name="Notepad" price="2.49"/>
			<fx:Object name="Mouse" price="21.79"/>
			<fx:Object name="Keyboard" price="32.99"/>
		</s:ArrayCollection>
	</fx:Declarations>
        <s:Label text="Select Supply:"/>
	<s:SpinnerListContainer width="200">
		<s:SpinnerList id="supplyList" width="100%" labelFunction="lblFunction" dataProvider="{suppliesAC}"/>
	</s:SpinnerListContainer>	

And a screenshot:

Selecting Items
You can programmatically set items to be selected in the SpinnerList via the selectedIndex or selectedItem properties. For instance, in the following we can bind the 2nd list to the 1st SpinnerList selectedIndex such as:

<s:VGroup>
	<s:Label text="Item #  Item"/>
	<s:SpinnerListContainer width="220">
		<s:SpinnerList id="list" width="20%">
			<s:dataProvider>
				<s:NumericDataProvider minimum="0" maximum="5" stepSize="1"/>
			</s:dataProvider>
		</s:SpinnerList>
		<s:SpinnerList id="supplyList" width="80%" labelField="name" dataProvider="{suppliesAC}" selectedIndex="{list.selectedItem}"/>					
	</s:SpinnerListContainer>
</s:VGroup>

Then as you interact with the left side numeric SpinnerList and select different indexes, the right SpinnerList selected item will change (probably need to download and run the source for yourself to see this best). Using the above code, when I select 1 instead of 0, the right side will select the Stapler item:

Styling List Items
You can style the SpinnerListItemRenderer to change the padding between the items for instance by setting a style such as:

        <fx:Style>
		@namespace s "library://ns.adobe.com/flex/spark";
		
		s|SpinnerListItemRenderer
		{
			paddingTop : 5;
			paddingBottom : 5;
			paddingLeft : 5;
			paddingRight : 5;
		}
	</fx:Style>

You could also override the SpinnerListItemRenderer class and modify the background color or alpha, such as the following simple custom item renderer:

package renderers
{
	import spark.components.SpinnerListItemRenderer;
	
	public class MySpinnerListRenderer extends SpinnerListItemRenderer
	{
		override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
		{
			graphics.beginFill(0x92ADC2, .7);
			graphics.lineStyle();
			graphics.drawRect(0, 0, unscaledWidth,unscaledHeight);
			graphics.endFill();
		}
	}
}

Here is the screenshot with the new item renderer applied to the SpinnerLists:

The sample project and source code is available HERE if you’d like to give it a whirl!

Filed in: Flex 4.5Flex 4.5/MobileFlex 4.6Flex Mobile Tags:

About the Author ()

Comments (17)

Trackback URL | Comments RSS Feed

  1. Sebastian G says:

    Holly thanks for the example and mostly thanks for helping us to get back to work and not worry about all this speculation.

  2. Hugo says:

    Do you think that people are just speculating !?

    About drops a bomb with the end of Flash Mobile with the worst communication of the history.

    Then one day after drops another bomb with the end of the Flex and that the HTML5 is the best (again the lawyers who are back to your shoulders are not developers).

    I’m moving now and ALL my flex coders friends to HTML5+CSS3+JS Frameworks+XPTO + notepad scripting brrrr (back to 90′s) because HTML5 is the best (said by own Adobe so how I’m to said the oposite ?).

    Regards.

  3. JCLang says:

    Thank you Holly for this sample.
    (I’m *not* moving from Flex)

  4. Michael McConnell says:

    Your posts are among the best, if not THE best, “how-to’s” I’ve seen for Flex development. Please keep them coming, hopefully, for many years to come.

    MLM

  5. Gunnar Karlsson says:

    @Holly.
    Thanks for a great blog.

    Some questions:

    When will Flex 4.6 be available for download?

    Can I build with the new components in Flash Builder 4.5.1 if I compile against SDK 4.6 and air 3, or do I need to install Flash Builder 4.6?

    Specifically to the Spinnerlist, can I skin the ‘glass’ selector to give it a different color from the spinner wheel?

    Last, have you moved more mx components to spark in 4.6?

    Thanks,
    Gunnar

  6. JCLang says:

    Hello,
    Flash Builder v4.6 => November, 29th

    As far as I understood, (almost) all the remaining mx components will be moved to Spark with the next-next release of (open source) Flex SDK.

    To use Spinner List *now*, the best way is to install the pre-release candidate Flash Builder v4.6.

  7. anon says:

    Great.
    Could you show how to adapt this into a horizontal spinner list? Now that would be really helpful.

    Thanks

  8. Georges says:

    Thanks for these tutorials.

    Love Flex Mobile. Most of our developments are AIR packaged mobile Apps :)

  9. VivD says:

    Thanks for the post.
    I’ve tried skinning the spinnerlist using styles, custom skins but can’t for the life of me get the gray background to go. I’m able to get it to look black but when I change the alpha value to anything less than 1 it starts looking grayish.

    Is there a way I can get rid of that.

    What I’m looking to do is get a fully black but slightly (alpha = 0.7) transparent spinner list.

  10. Jamie C says:

    Hello and thank you for these samples. I am new to Flash Builder and returning to programming after over a decade away…so may as well just be new altogether. Could someone provide a simple examples of how to process a math equation between 2 number that may appear in 2 spinner lists. I am doing well with presentation of text information, but an currently stumped on producing and math equations. Thank you for any help. Happy New Year to all.

  11. Dany Dhondt says:

    Thanks Holly for another great tutorial.
    I’m struggling with (what seems) a trivial problem:
    In a spinnerlist, I’d like to add a suffix which is only shown after the selected item.
    An example: a spinnerlist with a numeric data provider from 0 to 59 should show “Minutes” after the selected number so that the user knows he/she is setting the minutes. Just like the timer app on an iPhone. Is this possible?
    Thx, Dany

  12. Alfredo Gago says:

    I was wondering the exact same thing as Dany Dhont, is there any way to add a suffix?

  13. hi Holly, it is a very useful tutorial. thanks for that. But i need to a spinner which comes to screen when user touch some box on the screen. I think this is a default functionality for ios but i couldnt find it. is there a way to do this without using as 3.0 tween? thanks.

  14. naveed says:

    I have tried out with this code but I at time to define spinner, it says that it is not mobile optimized. I am using 4.5.1 flash builder

Leave a Reply