The ActionBar class defines a component that includes title, navigation, and action content groups. The ActionBar control provides a standard area for navigation and action controls. It lets you define global controls that can be used from anywhere in the application, or controls specific to a view.
What Is The ActionBar
The ActionBar is a SkinnableComponent that contains a titleGroup, navigationGroup and actionGroup. Each of these Groups are populated by using their content properties titleContent, navigationContent and actionContent.

navigationGroup
The navigationGroup provides a consistent placement to the right of the titleGroup for application navigation buttons. When implementing an ActionBar in a mobile application it really comes down to the needs and feel of the application in question. The ActionBar was pretty much born out of a visual design pattern for consistency and user familiratity.
Think of the browser, something most people use almost everyday. This is an ActionBar for the desktop. You have the Back button navigation on the left, the url title in the middle and action items such as search on the right. The navigation items are usually global to the application and sometimes to the View itself.
There are three ways to add items to a navigationGroup;
- Use the
navigationContent Array on the View or ViewNavigator declarativly through MXML.
- This allows the least flexibility.
- Use the
navigationContent property on the View or ViewNavigator.
- This allows the
View to properly fire property change events and change state.
- Use ActionScript to add items through the
IVisualElementContainer interface.
- This allows fine grained control of the display list without thinking about what already exists in the
navigationContent.
- Not recomended but possible.
navigationContent MXML Example:
<s:navigationContent>
<s:Button icon=@Embed(source='/assets/home_icon.png')
click="dispatchEvent(new Event('homeClick'))"/>
</s:navigationContent>
ActionScript navigationContent Example (inside a View):
// create a new button
var element:Button = new Button();
element.label = "New Button";
// set the new content
navigationContent = [element];
ActionScript display list Example (inside a View):
// get the actionBar from the parent navigator
var actionBar:ActionBar = navigator.actionBar;
// remove all elements from the navigationGroup
actionBar.navigationGroup.removeAllElements();
// create a new button
var element:Button = new Button();
element.label = "New Button";
// ... add handlers etc
// add the button to the navigationGroup
actionBar.navigationGroup.addElement(element);
Note: Using actionscript means you are bypassing the built in mechanism of navigatorContent declarativly to add items from the navigationGroup. This is sometimes needed for dynamically updating the ActionBar's navigation because something about the applications state changed relative to what was initially implemented. Or you are using an application framework with mediators or commands.
titleGroup
The titleGroup is the exception to the above rule when using the ActionBar‘s content properties. The ActionBar title property when set creates a titleDisplay that is placed inside the titleGroup created in the ActionBarSkin. When a title String is not set on the ActionBar or parent IViewNavigator, the titleGroup is still created. The default titleDisplay component the skin creates is an internal TitleDisplayComponent that wraps two StyleableTextField components to create a title shadow effect.
You may be wondering why the titleDisplay is created when you can set the titleContent of the ActionBar. The above functionality allows for a default implemetation of the title property. Instead of having to put a Label inside the titleGroup every time you use the ActionBar, by default the title will be placed in the titleDisplay created in ActionBarSkin.createChildren().
Style the titleDisplay
s|ActionBar #titleDisplay {
color:#F7F7F7;
textShadowAlpha:1;
}
Note: To use a TypeSelector such as s|ActionBar, you must define these from within the main application’s css or external css file.
actionGroup
The actionGroup provides a consistent placement to the full right that define actions the user can take in a view. As mentioned witht the navagationGroup, the actionGroup will contain items such as a search button or even an overflow action menu.
The actionGroup uses the same pattern for population as the navigationGroup(see above). The actionContent Array will be used to assign controls to the actionGroup instance.
Layouts
The navigationGroup and actionGroup also have sibling properties in navigationLayout and actionLayout. These added properties allow the developer to target specific padding, gaps and alignment for each group. Not adding these proxied properties in the ActionBar would mean you would have to set a new Group for each content if you wanted to change any of the charateristics of their layouts.
What Is The ActionBar Used For
The ActionBar is used for a consistent placement of title, navigation and actions. The component also very closely follows the existing ActionBar user interface pattern defined by most mobile OSs and browsers.
What Is The ActionBarSkin
The ActionBarSkin is an actionscript class that creates the ActionBar‘s skin parts, border and paints the background gradient.
SkinParts
navigationGroup:Group – defines the appearance of the navigation area of the component.
titleGroup:Group – defines the appearance of the title area of the component.
titleDisplay:IDisplayText – defines the appearance of the title text in the component.
actionGroup:Group – defines the appearance of the action area of the component.
Styles
How to style the default ActionBarSkin;
- Use the
chormeColor style to set the backgrounds gradient color.
- Use the
backgroundAlpha style to set the background gradient transparency.
- Use the padding styles to offset all content Groups.
s|ActionBar {
chromeColor:#3399FF;
backgroundAlpha:0.4;
}

Custom skin
To illustrate how to skin these archaic mobile skins lets say we want our own gradient and botom border.
package skins
{
import flash.display.GradientType;
import flash.geom.Matrix;
import spark.skins.mobile.ActionBarSkin;
public class MyActionBarSkin extends ActionBarSkin
{
private static var colorMatrix:Matrix = new Matrix();
private var mFillColors:Array = [0xCCCCCC, 0xFFFFFF, 0xBCBCBC];
private var mFillAlphas:Array = [1, 1, 1];
private var mFillRatios:Array = [0, 50, 255];
private var mLineColor:uint = 0x333333;
private var mLineWeight:int = 2;
public function MyActionBarSkin()
{
super();
borderClass = null;
}
override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void
{
var fillColors:Array = (getStyle("actionBarColors") == null) ? mFillColors : getStyle("actionBarColors");
var fillAlphas:Array = (getStyle("actionBarAlphas") == null) ? mFillAlphas : getStyle("actionBarAlphas");
var fillRatios:Array = (getStyle("actionBarRatios") == null) ? mFillRatios : getStyle("actionBarRatios");
var lineColor:uint = (isNaN(getStyle("lineColor"))) ? mLineColor : getStyle("lineColor");
var lineWeight:int = (isNaN(getStyle("lineWeight"))) ? mLineWeight : getStyle("lineWeight");
colorMatrix.createGradientBox(unscaledWidth, unscaledHeight, Math.PI / 2, 0, 0);
graphics.beginGradientFill(GradientType.LINEAR, fillColors, fillAlphas, fillRatios, colorMatrix);
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.endFill();
graphics.beginFill(lineColor, 1);
graphics.drawRect(0, unscaledHeight - lineWeight, unscaledWidth, lineWeight);
graphics.endFill();
}
}
}

Whats going on in that code?
- Create a new
MyActionBarSkin based off of the ActionBarSkin
- Create a constructor that nulls out the border shadow (FXG)
- Override the
drawBackground() method to disabled ActionBarSkin from painting it’s background gradient based of chromeColor
- Make up some new styles for our implementation so we can change things from the outside with CSS
actionBarColors, actionBarAlphas, actionBarRatios, lineColor, lineWeight
- Create a
Matrix box for gradient painting
- Use
Graphics.beginGradientFill() to paint the custom background gradient
- Use
Graphics.drawRect() to paint the bottom border line
Implementing the new skin
CSS code
s|ActionBar s|Button {
color:#333333;
textShadowAlpha:0;
}
s|ActionBar #titleDisplay {
color:#333333;
textShadowAlpha:0;
}
s|ActionBar {
skinClass:ClassReference("skins.MyActionBarSkin");
chromeColor:#BEBEBE;
paddingTop:0;
paddingBottom:0;
/* add the new styles to override the base styles set in the skin*/
}
The message in the example is, with a little code, you can create vast amounts of reusable skins that are styled with your own custom CSS. Adobe purposly made skins basically styleless because there are somany different use cases out there. They leave it up to the developer to choose between FXG, Bitmaps or the programmatic approach with draws fast and is reusable.
Notes:
- Setting defaults in the code is a good way to make your skin work out of the box.
getStyle() is NOT an expensive method call, setStyle() is expensive.
- Making the default mutable style properties in the skin subclass protected allows the the developer to choose between actionscript and CSS. Properties can be updated in a subclass by setting them in the constructor without having to reimplement the drawing logic of the superclass.
- The above class is simple and is not applying DPI resolution adjustments.
- Note that this could be done using media quires in CSS adjusting the
lineWeight style
What Are The ActionBar States
The ActionBar state;
- title –
title with no actionContent or navigationContent
- titleWithAction -
titlewith actionContent and no navigationContent
- titleWithNavigation -
titlewith navigationContent and no actionContent
- titleWithActionAndNavigation -
titlewith navigationContent and actionContent
- titleContent –
titleContent with no title, actionContent or navigationContent
- titleContentWithAction –
titleContent with actionContent and no title or navigationContent
- titleContentWithNavigation –
titleContent with navigationContentand no title or actionContent
- titleContentWithActionAndNavigation
- titleContent with actionContent and navigationContent and no title
Conclusion
The ActionBar is a very usefull component based on established user interface design patterns. The key to using the ActionBar is understanding how it fits into the ViewNavigatorApplication and View. The ActionBar can also be used as a stand alone component in a regualr spark Application. Using the component in this manner requires the developer to wire everything up. The former, Adobe has already done some heavy lifting for the developer.
I will be writting more in depth about the ActionBar when the series progresses to ViewNavigators.
About the Author
Michael Schmalle has been developing Adobe Flex and the Flash Player since Flash version 5 (2002). He has numerous open source projects in ActionScript3 (including an ActionScript3 parser/lexer DOM for reading and writing AS3 source code) and Flex (user interface components). He has also been an active participant in the Flex community (just goolge him or Teoti Graphix, LLC) since 2004. He also realizes technologies change and is actively developing user interface components and applications on the Google Android mobile platform.
See Teoti Graphix. LLC.
GIT: https://github.com/teotigraphix
Twitter: http://twitter.com/TeotiGraphix/
Recent Comments