Flex Mobile Development: Creating Dialog Windows
Ever wondered how to create a modal dialog window in Flex mobile applications? For example, you may want to ask the user for a confirmation when he performs a delete operation or maybe to select an item from a list. Well, if you don’t know how to do it, then read on.
Flex has a class that just does this: SkinnablePopUpContainer. SkinnablePopUpContainer extends SkinnableContainer class and has a very simple API you can use in order to “open” and “close” the dialog.
Understanding SkinnablePopUpContainer
Because SkinnablePopUpContainer extends the SkinnableContainer it is extremely easy to create any kind of dialog window you want. You can create a new MXML component that extends the SkinnablePopUpContainer. Then you set a layout manager that works for you (VerticalLayout, HorizontalLayout). And finally, you add the UI components you need – labels, buttons, lists, and so on.
Suppose you want to create a simple alert window that looks like this:

Here is the code to implement this (as a new MXML component that extends SkinnablePopUpContainer):
<?xml version="1.0" encoding="utf-8"?> <s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" backgroundColor="0x898989"> <s:layout> <s:VerticalLayout horizontalAlign="center"/> </s:layout> <s:Label text="The contact was saved" width="100%" textAlign="center"/> <s:Button label="OK" width="100%" click="this.close()"/> </s:SkinnablePopUpContainer>
The API for controlling the SkinnablePopUpContainer is pretty simple:
- To open or display the window you create a new instance and then call the open() method of SkinnablePopUpContainer. This method has two arguments. The first argument is the display object container where it will be created. The second argument is a flag that tells Flex if the window will be modal or not.
- To close the window and send data from the window to the application you use the close() method of SkinnablePopUpContainer. This methods also has two arguments. The first argument is a flag. You can set this to true if, for example, the user clicked the OK button, and false otherwise. If you want to send some data back to the application you use the second argument. For example, if you have a TextInput in your dialog and you want to send the text you will use this second argument.
- To listen for the close event and read the data sent from the SkinnablePopUpContainer you have to register an event listener on the SkinnablePopUpContainer. The event type is PopUpEvent. PopUpEvent has two properties that you can use to read the flag and data set when calling the close() method: commit and data.
Here is an example of how to open a SkinnablePopUpContainer component and read the flag/data when it is closed:
//create the component and open it
var alertWindow:SkinnablePopUpContainer = new SkinnablePopUpContainer();
alertWindow.addEventListener(PopUpEvent.CLOSE, onAlertClose, false, 0, true);
alertWindow.width = stage.width;
alertWindow.height = stage.height / 2;
alertWindow.x = 0;
alertWindow.y = 100;
alertWindow.open(this, true);
private function onAlertClose(event:PopUpEvent):void {
trace(event.commit);
trace(event.data);
alertWindow = null;
}
Creating custom dialog windows
Once you understand how to use the SkinnablePopUpContainer it is pretty simple to create any kind of dialog window you might need: confirmation messages, simple alerts, pop up lists, and so on. Here is the code for a confirmation window that has two buttons (Yes and No) and lets you set the message text:
-
<?xml version="1.0" encoding="utf-8"?>
-
<s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
-
xmlns:s="library://ns.adobe.com/flex/spark"
-
backgroundColor="0×898989" width="400">
-
<s:layout>
-
<s:VerticalLayout gap="20" paddingBottom="10" paddingLeft="30" paddingRight="30" paddingTop="30" horizontalAlign="center"/>
-
</s:layout>
-
<fx:Script>
-
<![CDATA[
-
-
-
[Bindable]
-
return _message;
-
}
-
-
_message = value;
-
}
-
-
super.close(commit);
-
}
-
-
]]>
-
</fx:Script>
-
-
<s:Label text="{message}" width="100%" textAlign="center"/>
-
-
<s:HGroup width="100%">
-
<s:Button label="Yes" width="50%" click="onClick(true)"/>
-
<s:Button label="No" width="50%" click="onClick(false)"/>
-
</s:HGroup>
-
-
</s:SkinnablePopUpContainer>
And here is how this component look on my Android phone:

And here is the code for a pop up list that lets you to set the title, the list’s data provider, the list’s label field, the list’s initial selected items, and multiple selections (you can retrieve the selected items by listening for PopupEvent.CLOSE and reading the data attribute).
-
<?xml version="1.0" encoding="utf-8"?>
-
<s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
-
xmlns:s="library://ns.adobe.com/flex/spark"
-
backgroundColor="0×898989" width="400">
-
<s:layout>
-
<s:VerticalLayout gap="20" paddingBottom="10" paddingLeft="30"
-
paddingRight="30" paddingTop="30" horizontalAlign="center"/>
-
</s:layout>
-
<fx:Script>
-
<![CDATA[
-
import mx.collections.ArrayCollection;
-
-
private var _dataProvider:ArrayCollection;
-
private var _selectedItems:Vector.<Object>;
-
-
[Bindable]
-
public function get selectedItems():Vector.<Object> {
-
return _selectedItems;
-
}
-
-
public function set selectedItems(v:Vector.<Object>):void {
-
_selectedItems = v;
-
}
-
-
[Bindable]
-
return _allowMultipleSelection;
-
}
-
-
_allowMultipleSelection = v;
-
}
-
-
[Bindable]
-
return _labelField;
-
}
-
-
_labelField = v;
-
}
-
-
[Bindable]
-
public function get dataProvider():ArrayCollection {
-
return _dataProvider;
-
}
-
-
public function set dataProvider(v:ArrayCollection):void {
-
_dataProvider = v;
-
}
-
-
super.close(commit, list.selectedItems);
-
}
-
]]>
-
</fx:Script>
-
-
<s:Label text="Select an item:" width="100%"/>
-
-
<s:List id="list" width="100%" height="100%"
-
dataProvider="{dataProvider}"
-
labelField="{labelField}"
-
allowMultipleSelection="{allowMultipleSelection}"
-
selectedItems="{selectedItems}"/>
-
-
<s:HGroup width="100%">
-
<s:Button label="OK" width="50%" click="onClick(true)"/>
-
<s:Button label="Cancel" width="50%" click="onClick(false)"/>
-
</s:HGroup>
-
-
</s:SkinnablePopUpContainer>
And here is the component running on my phone:

Skinning
The two custom dialog windows I showed you in the previous section use the default look and feel. What about skinning a SkinnablePopUpContainer? There is a Flex class that provides the default skin for a SkinnablePopUpContainer: SkinnablePopUpContainerSkin. By creating a skin that extends this default skin you can change the background of the component quite easily. If you look at the SkinnablePopUpContainerSkin skin you’ll notice that it has a rect with the id equal to background. This is the starting point to change the default background. You can draw additional stuff on top of this background or replace it alltogether with an FXG or PNG file.
For the rest of the UI components used in a SkinnablePopUpContainer (buttons, text inputs, labels, and so on) you will create additional skins and/or use CSS. Here is a screenshot with the same confirmation window but this time using a custom skin:
Here is the skin class used to customize the confirmation window presented in the previous section:
-
<?xml version="1.0" encoding="utf-8"?>
-
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
-
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
-
alpha.disabled="0.5" xmlns:skins="org.corlan.dialog.skins.*">
-
-
<fx:Metadata>
-
<![CDATA[
-
/**
-
* @copy spark.skins.spark.ApplicationSkin#hostComponent
-
*/
-
[HostComponent("spark.components.SkinnablePopUpContainer")]
-
]]>
-
</fx:Metadata>
-
-
<s:states>
-
<s:State name="normal"/>
-
<s:State name="disabled"/>
-
<s:State name="closed" stateGroups="closedGroup"/>
-
<s:State name="disabledAndClosed" stateGroups="closedGroup"/>
-
</s:states>
-
-
<!– Transitions for open and close –>
-
<s:transitions>
-
<s:Transition fromState="closed" toState="normal" autoReverse="true">
-
<s:Fade duration="150" target="{chrome}"/>
-
</s:Transition>
-
-
<s:Transition fromState="disabledAndClosed" toState="disabled" autoReverse="true">
-
<s:Fade duration="150" target="{chrome}"/>
-
</s:Transition>
-
-
<s:Transition fromState="normal" toState="closed" autoReverse="true">
-
<s:Fade duration="150" target="{chrome}"/>
-
</s:Transition>
-
-
<s:Transition fromState="disabled" toState="disabledAndClosed" autoReverse="true">
-
<s:Fade duration="150" target="{chrome}"/>
-
</s:Transition>
-
</s:transitions>
-
-
<!— Defines the background and content group used by this skin. –>
-
<s:Group id="chrome" left="0" right="0" top="0" bottom="0" visible.closedGroup="false">
-
<!—
-
Defines the appearance of the SkinnablePopUpContainer class‘s background.
-
In this case a FXG file is used to draw the background.
-
–>
-
<skins:BackGroundAlert id="background" left="0" right="0" top="0" bottom="0"/>
-
<!— @copy spark.components.SkinnableContainer#contentGroup –>
-
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" minWidth="0" minHeight="0">
-
<s:layout>
-
<s:BasicLayout/>
-
</s:layout>
-
</s:Group>
-
</s:Group>
-
-
</s:Skin>
And this is the FXG used by the skin class to draw the background:
-
<?xml version="1.0" encoding="utf-8" ?>
-
<Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008"
-
xmlns:d="http://ns.adobe.com/fxg/2008/dt"
-
xmlns:flm="http://ns.adobe.com/flame/2008"
-
scaleGridLeft="10" scaleGridTop="10"
-
scaleGridRight="90" scaleGridBottom="90">
-
<Rect width="100" height="100" radiusX="10">
-
<fill>
-
<LinearGradient x="190.417" y="0" scaleX="361.667" rotation="90">
-
<GradientEntry ratio="0" color="#FFFFFF"/>
-
<GradientEntry ratio="0.0424137" color="#E1DBCE"/>
-
<GradientEntry ratio="0.0886452" color="#CEC3AE"/>
-
<GradientEntry ratio="0.139618" color="#C4B89F"/>
-
<GradientEntry ratio="0.208589" color="#C2B59B"/>
-
<GradientEntry ratio="0.588957" color="#C2B59B"/>
-
<GradientEntry ratio="0.758513" color="#C0B399"/>
-
<GradientEntry ratio="0.852955" color="#B2A58E"/>
-
<GradientEntry ratio="0.932468" color="#918372"/>
-
<GradientEntry ratio="1" color="#594A42"/>
-
</LinearGradient>
-
</fill>
-
<stroke>
-
<SolidColorStroke weight="3"/>
-
</stroke>
-
</Rect>
-
</Graphic>
Download
You can download a working Flex project that includes all the code used in this article from here.
Comments
5 Responses to “Flex Mobile Development: Creating Dialog Windows”
Leave a Reply




Very useful. Thanks for posting that !
hi, i am reading your blog while i am preparing to show how to create a preference view in native android and mobile flex. :) thanks for the post
I wanted to finally share my dialog example using e-skimo :) http://blog.flexnroses.com/?p=126
Hi this Popup list works like a charm thank you, But I have noticed an error when you try to populate the array with only one record. Can you try it out and let me know
Why is SkinnablePopUpContainerSkin extending the mxml skin classes ? They say mxml skin with state are a performance killer for mobile…
This popup is a bit sluggish on iPad1, I was forced to recreate the skin base on MobileSkin.