How to Style Items in a Flex 4 Spark List

I’ve often heard it said that while Flex has a knack for making difficult tasks easy, it also has the same knack for making seemingly easy tasks difficult. While I agree that on occasion it seems that way up front, I usually find that the solution isn’t usually difficult, just difficult to find.

That was the case I found when recently working with the Spark List Component. Dynamically assigning an ArrayList as a Spark List’s data provider was a quick task and everything worked as expected. I was thrilled. Now I just had to tweak the spacing between the list items and I’d be finished. Easy, right? Ultimately the answer is yes. However, arriving at the solution took me a couple of hours!

The Spark List component automatically adds cool rollover and select effects. It also allows you to change rollover colors, set the width, and adjust the font size with simple attributes. What it doesn’t let you do so easily is set the spacing between list items. ( Note that I’m referring to a dynamically populated List, not one in which you define each item individually where you have the luxury of modifying the attributes of each item ).

Here’s some code to demonstrate the situation:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
	xmlns:s="library://ns.adobe.com/flex/spark"
	xmlns:mx="library://ns.adobe.com/flex/mx"
	preinitialize="preinitHandler(event)"  >
	<fx:Script>
		<![CDATA[
		import mx.collections.ArrayList;
		import mx.events.FlexEvent;

		[Bindable]
		private var monthsList:ArrayList;

		protected function preinitHandler(event:FlexEvent):void {
			monthsList = new ArrayList(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"]);
		}
		]]>
	</fx:Script>

	<s:List id="months" dataProvider="{monthsList}" />
</s:Application>

The code above populates a Spark List with months. Very quick and easy! But now I want to close up the space between the months. Simple padding or gap attribute on the list, right? Nope. lineheight? No. Custom VerticalLayout? Uh uh. Google? Majority of results show examples where each item is defined manually…that doesn’t help either.

The answer it turns out is to define a custom ItemRenderer. This is used to tell the results how they should render when displayed. Common sense, right? And it’s pretty easy to do too:

<s:List id="months" dataProvider="{monthsList}" >
	<s:itemRenderer>
		<fx:Component>
			<s:ItemRenderer>
				<s:Label text="{data}" paddingTop="3" paddingBottom="3" fontSize="11" />
			</s:ItemRenderer>
		</fx:Component>
	</s:itemRenderer>
</s:List>

You can style the output any way you like by styling the label in the ItemRenderer. Note that if your data source contains multiple “fields” with property names, you’ll need to tweak the label text value slightly to reflect the property name of the value you’ll be displaying. So, instead of {data}, you would use something like {data.propertyName}.

Bonus tip: For reusability and flexibility you can define the the ItemRenderer as a separate MXML file and assign it to the itemRenderer property of the Spark List. Even better, you can add the Label style to a style sheet and use it throughout your application.

-rG

Font Embedding with Flex 4

I’ve been noodling around a bit with Flash Builder 4 lately. After creating a few simple apps I decided to look into font embedding. There are quite a few posts to be found via Googling about embedding fonts in Flex. Some are very good, others not so much, but I think I managed to compile the info into a useful example. My goal was to create custom font swfs, load them into flex, and then apply them to a text field through the use of some type of selector.

1. Create the Font SWF

Embed CharactersThe first step is to use Flash to create a font swf. To do so, create a new Flash document and add a dynamic text field to the stage. Select the text field and choose the font you want to use in your Flex application. Next, click the Character Embedding button from the Property panel and choose the characters that you want available to your Flex application. Choose only the characters you need as each extra character will add unnecessary size. Finally, publish the swf and place a copy in your Flex application folder.

Make a font swf for each font you want to use in your Flex application then close Flash.

2. Embed the Font SWF

The next step is to pull those font swfs into your Flex application and create classes, or styleNames, for them. This is done inside the fx:Style tag (mx:Style in Flex 3)

<fx:Style >
		@namespace s "library://ns.adobe.com/flex/spark";
		@namespace mx "library://ns.adobe.com/flex/mx";


		@font-face	{
			src: url("fonts/calvin.swf");
			font-family: "Calvin and Hobbes";
		}
		@font-face {
			src:url("fonts/lcd.swf");
			font-family:"LCD";
		}
		@font-face {
			src:url("fonts/ransom.swf");
			font-family:"RansomNote";
		}

		.calvin {font-family: "Calvin and Hobbes";}
		.lcd {font-family: "LCD";}
		.ransom {font-family: "RansomNote";}

	</fx:Style>

Note that the font-family is the name of the font as listed in the Flash IDE. Once this is done I can assign the styleNames “smack”, “square”, and “curlz” to an mx:Text field and it will be presented in that font, something like this:

<mx:Text id="myText" text="This is my text" styleName="calvin"  />

If you stop here you will have a text field using your embedded font.

3. Create a Font Selector

We can take this an additional step by adding a radio button group and a simple function to allow dynamic switching between fonts:

<fx:Declarations>
	<s:RadioButtonGroup id="radiogroup1"/>
</fx:Declarations>
<mx:Text id="myText" x="159" y="28" text="Select another font" styleName="calvin"   fontSize="20"/>
<s:RadioButton id="calvin" x="10" y="10" label="Calvin" groupName="radiogroup1" click="handleChangeFont(event)" selected="true"/>
<s:RadioButton id="lcd" x="10" y="36" label="LCD" groupName="radiogroup1" click="handleChangeFont(event)"/>
<s:RadioButton id="ransom" y="62" label="Ransom Note" groupName="radiogroup1" click="handleChangeFont(event)" x="10"/>

Note that, as an id for each radiobutton I used the class name they will invoke. This will allow me to use only one line of code in one function to assign the appropriate styleName to my text field:

<fx:Script>
	<![CDATA[

		protected function handleChangeFont(evt:Event):void {
		myText.styleName = evt.target.id;
	        }

	]]>
</fx:Script>

The finished product looks something like this:

Right-click on the swf and then click "View Source" to view or download the source.