Flex Mobile Development – Callout Component Sample (with source)

来源:互联网 发布:转视频格式软件 编辑:程序博客网 时间:2024/06/07 19:01

Flash Builder 4.6 and Flex 4.6 are currently in pre-release and this is the first of a series of posts highlighting the new features with sample code. Most of the new Flex 4.6 components were created for tablet application development where more screen real estate is available to work with.

The first component I’ll highlight in this series is the new Spark Callout component. TheCallout is used to define a pop-up container for your mobile application where you may want to show actions to take, accept input or simply display some information. You can use any of the current UI components supported for mobile within aCallout, including even a mobile ViewNavigator. The component features an arrow that points to the owner of theCallout (the component that called open() on it). If you’ve done any Objective-C programming for iPad, you may know this as thePopover component.

Here’s an example of it in use in a tablet application Christophe and I will be working with at RIA Unleashed in Boston next week:

I created a sample tabbed application that I’m making available here so you can check out some different ways to useCallout‘s in your applications. I also included some explanatory text below. It’s nothing fancy but should be useful in your mobile application development!

Expanding Callout initially
In the first tab of the sample code I show an example of opening the callout from theCalloutButton on creationComplete, in case there’s informational text you want to have immediately available. Here’s a screenshot:

Here’s the code snippet for the above:

<s:CalloutButton id="cb2" icon="{addIcon}" verticalPosition="after" creationComplete="cb2.openDropDown()"><s:calloutContent><s:BorderContainer backgroundColor="blue" color="0xFFFFFF" borderWeight="2" width="280" height="150" cornerRadius="5"><s:layout><s:VerticalLayout paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" gap="5"/></s:layout><s:HGroup verticalAlign="middle" horizontalAlign="left"><s:Image source="@Embed(source='help.png')" id="helpIcon"/><s:Label text="Getting Started"/></s:HGroup><s:TextArea text="Tap this button to get started adding buddies to your buddy list immediately." color="0x000000" width="100%"skinClass="spark.skins.mobile.TextAreaSkin" editable="false"/></s:BorderContainer></s:calloutContent></s:CalloutButton>

Positioning the Callout
There are two properties to position the Callout component relative to it’s owner,horizontalPosition and verticalPosition. You can leave the defaults of auto by not setting them at all and the position be set based on the aspect ratio of the screen (portrait or landscape) for theCallout to fit with minimal owner overlap and screen bounds adjustments. Besidesauto, you can manually set the horizontal and vertical position to before, start, middle, end,and after as desired.

Tab 3 in the sample application shows how setting the different positions will affect theCallout, try out the different settings in the SpinnerList controls (also new to 4.6):

Closing the Callout
When using the CalloutButton, clicking outside of the Callout container will always close it, since it’s non-modal. Otherwise, you need to call thecloseDropDown() method to close it though, as shown in the code snippet from the sample:

<fx:Script>    <![CDATA[import spark.events.ViewNavigatorEvent;protected function button1_clickHandler(event:MouseEvent):void{trace(event.target.label + " clicked! " + cb.isPopUp);cb.closeDropDown();}    ]]></fx:Script><s:CalloutButton id="cb" label="Action Callout" verticalPosition="after" calloutDestructionPolicy="never"><!-- layout the callout content here --><s:calloutLayout><s:VerticalLayout paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" horizontalAlign="center" gap="5"/></s:calloutLayout><s:calloutContent><s:Button label="Search" width="{btn.width}" click="button1_clickHandler(event)"/><s:Button label="Followers" width="{btn.width}" click="button1_clickHandler(event)"/><s:Button label="Following" width="{btn.width}" click="button1_clickHandler(event)"/><s:Button id="btn" label="Direct Messages" click="button1_clickHandler(event)"/></s:calloutContent></s:CalloutButton>

This screenshot from Tab 1 shows the above code with the expanded Callout container:

When using the Callout component itself (rather than the CalloutButton), you can call a close() method to close the Callout and listen for the event to get the data from the selection. See the next section on passing data for a code snippet. The list calls theclose() method of the callout passing the selectedItem.

NOTE: In my sample code I added code to close the Callout programmatically uponviewDeactivate so it would close when a different tab is selected.

Passing Data from Callout
Since the Callout component extends SkinnablePopUpContainer, we can use theclose() method to pass back data setting the commit property to true in the first parameter and the data to pass back in the second parameter.


Here’s the source code for MyCallout.mxml:

<?xml version="1.0" encoding="utf-8"?><s:Callout xmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark"><fx:Declarations><s:ArrayCollection id="ac"><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></fx:Declarations><s:VGroup paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" horizontalAlign="center"><s:List id="list" dataProvider="{ac}" width="240" change="close(true, list.selectedItem)"/></s:VGroup></s:Callout>

Then we can listen for the close event on the callout that uses it and get the data back to use as desired, such as:

<components:MyCalloutComp id="callout" height="300" close="location.text=event.data" verticalPosition="after"/>

The result is that the location text is populated with the selected list item from the Callout:

Skinning
The Callout component extends from SkinnablePopUpContainer and is therefore skinnable. Take a look at theCalloutSkin.as file in your Flex 4.6 SDK for starters. Mine is located on my Mac at: /Applications/Adobe Flash Builder 4.6/sdks/4.6.0/frameworks/projects/mobiletheme/src/spark/skins/mobile. The last tab in the sample code shows some changes to theCallout skin by using a custom skin. You could even customize the arrow further by looking into theCalloutArrow.as code, which is what is currently used by the skin for drawing the arrow.CalloutArrow actually extends UIComponent so you have a lot of flexibility to customizing your arrow if desired. In my simple example, I showed how you could change the width and height of the arrow in the skin as well as the frame and border width etc to create a different look (keep in mind I am clearly no designer, just giving you some options to play with;) )!!

Here’s the code for the custom Callout skin:

package skins{import mx.core.DPIClassification;import spark.skins.mobile.CalloutSkin;import spark.skins.mobile.supportClasses.CalloutArrow;public class MyCalloutSkin extends CalloutSkin{public function MyCalloutSkin(){switch (applicationDPI){// add in other cases for 240 and 320 DPI above if needed// right now most tablets are 160case DPIClassification.DPI_160:{backgroundCornerRadius = 8;frameThickness = 8;arrowWidth = 82; //default is 52 at 160 DPIarrowHeight = 46; // default is 26 at 160 DPIborderColor=0xAA0D0A;borderThickness=5;frameThickness=9;contentCornerRadius = 40;break;}}}}}

The Tab 4 View class code is shown below with the custom skin applied. You can also see that it uses an inlineCallout component rather than a separate MXML file:

<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark" title="Inline Callout with Skin"  xmlns:components="components.*"viewActivate="view1_viewActivateHandler(event)" viewDeactivate="callout.close()"><fx:Script><![CDATA[import components.MyCalloutComp;import spark.events.ViewNavigatorEvent;protected var callout:Callout1;protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void{callout=new Callout1();}]]></fx:Script><fx:Declarations><fx:Component className="Callout1"><s:Callout xmlns:fx="http://ns.adobe.com/mxml/2009"           xmlns:s="library://ns.adobe.com/flex/spark" skinClass="skins.MyCalloutSkin" verticalPosition="after"><s:VGroup paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" horizontalAlign="center"><s:Label text="My Story" fontWeight="bold" fontSize="30" color="0xAA0D0A"/><s:TextArea text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur accumsan felis ac tortor aliquam iaculis. Phasellus hendrerit viverra enim, sit amet scelerisque lectus dictum at. Aenean sodales nisi sed leo congue et porttitor ligula vehicula.Pellentesque turpis massa, suscipit vel fermentum quis, dignissim sed ipsum. Nulla aliquet libero adipiscing risus lobortis eleifend quis at velit. Duis at leo urna.Praesent facilisis faucibus neque, ut ullamcorper lacus gravida a. Donec vel iaculis sapien." skinClass="spark.skins.mobile.TextAreaSkin" width="90%" editable="false"/></s:VGroup></s:Callout></fx:Component></fx:Declarations><s:layout><s:VerticalLayout paddingTop="40" paddingBottom="8" paddingLeft="8" paddingRight="8" gap="15"  horizontalAlign="center"/></s:layout><s:TextArea skinClass="spark.skins.mobile.TextAreaSkin" width="90%"text="You can specify a Callout component inline rather than in separate MXML as shown in this sample. You can also apply a custom skin since the Calloutcomponent extends the SkinnablePopUpContainer class. Click the story icon below to invoke a skinned callout."/><s:Image id="img" source="@Embed(source='text48.png')" click="callout.open(img)"/></s:View>

Download the source for the sample tabbed application HERE.

Check out this article to find about more features available in Flash Builder 4.6/Flex 4.6 andsign up for the prerelease today if you haven’t already!

原创粉丝点击