- Understanding Style Properties
- Applying Styles Inline
- Applying Styles Using CSS
- Style Precedence
- Working with Styles Using ActionScript
- Styling in Design View
- CSS Design View
- Themes
- Summary
Working with Styles Using ActionScript
So far, we've mostly discussed working with styles using MXML. If necessary, you can accomplish the same tasks, and more, using ActionScript. Perhaps your application requires a particular button to be red or green depending on the values of certain variables. You could execute a function that checks those variables and conditionally sets the backgroundColor style of your button. As with many things in application development, there are several ways to accomplish this, but let's have a look at how you might do it with ActionScript (see Listing 4-18).
To set a style on an instance of a component, you call the setStyle method available to any style-enabled component, passing it the name of the style property and the value you wish to set it to. This is basically the equivalent of specifying a style property inline in MXML. Because calling this method not only impacts the component on which it was called, but also any components contained within, it should be used judiciously. To get the current value of a style property using ActionScript, you use the getStyle method, which is a much lighter operation than setStyle.
Listing 4-18. Conditionally setting style properties using ActionScript
<mx:Script> <![CDATA[ public var valid:Boolean = true; public function changeButtonColor () : void { if ( valid == true ) { // make the background green myButton.setStyle('backgroundColor',0x00CC00); } else { // make the background red myButton.setStyle('backgroundColor',0xCC0000); } } ]]> </mx:Script> <mx:Button id="myButton" click="changeButtonColor()" />
Creating Stylable Widgets
It is common to composite two or more components to create a reusable widget for your application. For example, you might extend an HBox and stuff it with a TextInput and Button to create a SearchInputWidget to use throughout your application. Listing 4-19 demonstrates exactly that to create a component that looks like Figure 4-5.
Listing 4-19. Applying style to an element of a widget with an explicit class selector
<!-- SearchInput.mxml --> <?xml version="1.0" encoding="utf-8"?> <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" > <mx:TextInput width="100%" height="100%" /> <mx:Button label="Search" height="100%" styleName="searchInputButton" /> </mx:HBox>
Figure 4-5 A stylable SearchInput widget that combines a TextInput with a SearchButton
Notice in Listing 4-19 that the styleName of the button is set to searchInputButton. This approach exposes the style of the button so that it can be defined outside of the widget, but all instances of SearchInputWidget will have the exact same style. Although this is better than applying a bunch of inline styles to the button, there is still a better way. Changing the button definition as shown in Listing 4-20 allows you to customize each instance of the SearchInput widget differently (see Listing 4-21).
Listing 4-20. Applying style to an element of a widget using a dynamic class selector
... <mx:Button label="Search" height="100%" styleName="{getStyle('buttonStyleName')}" /> ...
Listing 4-21. Applying two different styles to two instances of the same widget
<local:SearchInputWidget buttonStyleName='redButton' /> <local:SearchInputWidget buttonStyleName='blueButton' />
For this trick to work, you must expose buttonStyleName as a style using metadata as shown in Listing 4-22. Style metadata tells the compiler which style can be used with a particular component, its format and data type, and whether children of this component should inherit this style.
Listing 4-22. Style metadata used to define a buttonStyleName style
[Style(name="buttonStyleName", type="String", inherit="no")]
Introducing the Style Manager
Behind all styling operations in Flex is the StyleManager. It is possible to access, modify, and define CSS selectors using ActionScript and the StyleManager. This opens a world of possibilities for creating dynamic styles or performing other tricks.
You can use ActionScript to directly access the selectors from the StyleManager to take an inside-out approach to styling. For example, you might define a selector that embeds several icons (see Listing 4-23). Next, from within your application, use ActionScript to access the values of that selector (see Listing 4-24). It's a pretty handy trick because it keeps all of your icons in one place.
Without this trick, you have to embed your assets within the component in which it will be used, which can get ugly if that component is buried deep in the application package structure. Imagine a SearchInput widget located in a com.cve.view.controls package. A reference to an icon located in an images folder at the root of the project might look something like Listing 4-25.
The StyleManager also enables you to load and unload entire style sheets at runtime, which enables you to create dynamic, on-the-fly customizations of your Flex application. For this to work, your style sheets must be compiled as SWF. Runtime styling is described at length in Exercise 4.1.
Listing 4-23. Several assets embedded in a single selector
.icons { wrenchIcon: Embed('images/wrench.png'); searchIcon: Embed('images/magnifier.png'); loginIcon: Embed('images/lock.png'): }
Listing 4-24. Accessing embed assets using the StyleManager
<Button icon="{StyleManager.getStyleDeclaration('.icons').getStyle('wrenchIcon')}" label="Customize" />
Listing 4-25. An ugly Embed statement within a component
[Embed(source="../../../../images/magnifyer.png")] public var searchIcon:Class;