| | {section} |
| | {column:width=80%} |
| | |
| | h2. Creating a Simple RIA Tutorial |
| | |
| | {adv-popup:Open New Window|http://www.adobe.com/support/documentation/en/flex/quick_start/overview/|896|720|no}Watch the video version of this tutorial.{adv-popup} |
| | |
| | h2. Application Overview |
| | |
| | !SimpleRIAFlickrSchematic_sm.png! |
| | {column} |
| | {column} |
| | {adbe-prev:http://learn.adobe.com/wiki/display/Flex/1c.+Code+Anatomy} |
| | {adbe-next:http://learn.adobe.com/wiki/display/Flex/Part+II.+Exchanging+Data} |
| | {rate:title=User rating|theme=dynamic|key=focal|display=default} |
| | {adbe-pod} |
| | |
| | h6. Learn more |
| | |
| | * {adbe-popup:http://livedocs.adobe.com/flex/3/html/layouts_01.html}Using Layout Containers{adbe-popup} |
| | * {adbe-popup:http://www.adobe.com/devnet/flex/articles/designview.html}Getting the Most Out of the Flex Builder Design View{adbe-popup} |
| | * {adbe-popup:http://labs.adobe.com/wiki/index.php/Flex_3:Feature_Introductions}Flex 3:Feature Introductions{adbe-popup} |
| | * {adbe-popup:http://www.adobe.com/devnet/flex/quickstart/using_data_binding/}Flex Quick Starts: Handling data{adbe-popup} |
| | * {adbe-popup:http://www.onflex.org/ted/2007/05/flex-over-xmlxsl.php}Flex over XML/XSL{adbe-popup} |
| | * {adbe-popup:http://www.adobe.com/devnet/flex/quickstart/using_item_renderers/}Flex Quick Starts: Building an advanced user interface{adbe-popup} |
| | * {adbe-popup:http://www.adobe.com/devnet/flex/quickstart/building_components_in_mxml/}Flex Quick Starts: Building custom components{adbe-popup} |
| | * {adbe-popup:http://www.adobe.com/devnet/flex/quickstart/using_data_binding/}Flex Quick Starts: Handling data{adbe-popup} |
| | {adbe-pod} |
| | {adbe-showhide} |
| | {column} |
| | {section} |
| | \\ |
| | {section} |
| | {column:width=80%} |
| | |
| | h2. Create a new Flex application project named FlickrRIA |
| | |
| | 1. In the Flex Builder IDE, select *File > New > Flex Project* and name the project *"FlickrRIA"*. |
| | |
| | 2. Accept the default location for the project and confirm that the *Application Type* is *Web Application* and that the *Server Technology* is set to *None*. |
| | |
| | 3. Click *Finish* to create the project. |
| | |
| | The FlickrRIA.mxml application file opens in the MXML editor. The editor is in Source mode. |
| | |
| | \\ |
| | |
| | h2. Format the Display |
| | |
| | 1. In the opening Application tag, delete the code *layout="absolute"*. |
| | |
| | 2. For the Application tag, add the *backgroundGradientColors* attribute with the value of *\[0xFFFFFF, 0xAAAAAA\]*, the *horizontalAlign* attribute with the value of *left*, the *verticalGap* attribute with the value of *15*, and the *horizontalGap* attribute with the value of *15*. |
| | {code} |
| | <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" |
| | backgroundGradientColors="[0xFFFFFF,0xAAAAAA]" |
| | horizontalAlign="left" |
| | verticalGap="15" horizontalGap="15" > |
| | {code} |
| | {column} |
| | {column} |
| | {adbe-pod} |
| | |
| | h6. LEARN MORE |
| | |
| | * The {adbe-popup:http://livedocs.adobe.com/flex/3/html/app_container_1.html} Application container{adbe-popup} is the root XML object. It contains all other objects. |
| | * Download a {adbe-popup:http://learn.adobe.com/wiki/download/attachments/5701770/Flex3GSE_SimpleRIA.zip}ZIP file{adbe-popup} that contains the completed application. |
| | * To import the project into Flex Builder, select File > Import Flex Project. |
| | {adbe-pod} |
| | {column} |
| | {section} |
| | \\ |
| | {section} |
| | {column:width=80%} |
| | |
| | h2. Use Design mode to lay out the search form |
| | |
| | 1. Click the *Design* button to change to the Design mode. Using the Design mode is the easiest way to layout a form in Flex Builder. |
| | |
| | !designview8a.jpg! |
| | |
| | 2. From the Components view, drag an *HBox* component from the Layout folder to the design area. Keep the default values of the component. The HBox component contains the label, input field, and button for the form and displays them horizontally. |
| | |
| | _Note:_ _The blue lines that appear in the design area help you position the component. When you release the component in the design area, it snaps into position._ |
| | |
| | !designview3b.jpg! |
| | |
| | 3. Drag the *Label* component from the Controls folder to the HBox component. |
| | |
| | !designview3a.jpg! |
| | |
| | 4. To change the default appearance of the Label component, double-click the *Label* component and enter *Flickr tags or search terms*. |
| | |
| | !designview9.jpg! |
| | |
| | 5. Drag the *TextInput* component from the Controls folder to the position following the Label component in the HBox. The TextInput component provides the user with a space to input search terms. |
| | |
| | !designview10.jpg! |
| | |
| | 6. Drag a *Button* component from the Controls folder to the position following the TextInput component in the HBox component. |
| | |
| | 7. Double-click the *Button* component and enter *Search* to change the default appearance. |
| | |
| | h2. Create the HTTPService object |
| | |
| | 1. Change to the Source mode. |
| | |
| | !sourceview.jpg! |
| | |
| | 2. Use the HTTPService component to call the Flickr service and return the results. _After_ the opening Application tag and _before_ the HBox component, create an *HTTPService* component. It does not have a closing tag. To the HTTPService component, add the *id* attribute with a value of *photoService*, the *url* attribute with the value of *\[http://api.flickr.com/services/feeds/photos_public.gne\]*, and the *result* attribute with the value of *photoHandler(event)*. The photoHandler event packages the service results. We create the {{{{photoHandler}}}} function later in this tutorial. |
| | {code} |
| | <mx:HTTPService id="photoService" |
| | url="http://api.flickr.com/services/feeds/photos_public.gne" |
| | result="photoHandler(event)"/> |
| | {code} |
| | {column} |
| | {column} |
| | {adbe-pod} |
| | |
| | h6. Working with Flickr |
| | |
| | * When working with Flickr, be sure to check out the |
| | {adbe-popup:http://www.flickr.com/guidelines.gne}Community Guidelines{adbe-popup} |
| | * And the {adbe-popup:http://www.flickr.com/services/api/tos/}API Terms of Use{adbe-popup} |
| | {adbe-pod} |
| | {adbe-pod} |
| | |
| | h6. LEARN MORE |
| | |
| | * Flex Builder is an {adbe-popup:http://en.wikipedia.org/wiki/Integrated_development_environment}Integrated Development Environment (IDE).{adbe-popup} |
| | * The IDE is built on {adbe-popup:http://www.eclipse.org} Eclipse{adbe-popup}. |
| | * Use {adbe-popup:http://livedocs.adobe.com/flex/3/html/overview_1.html}Flex Builder{adbe-popup} to create SWF files. |
| | * {adbe-popup:http://en.wikipedia.org/wiki/SWF}What is a SWF?{adbe-popup} |
| | * What are all those files in the {adbe-popup:http://livedocs.adobe.com/flex/3/html/ui_reference_3.html}Navigator{adbe-popup}? |
| | * {adbe-popup:http://livedocs.adobe.com/flex/3/html/projects_5.html}Where{adbe-popup} does Flex Builder save my projects? |
| | * Is it {adbe-popup:http://www.onflex.org/ted/2007/01/close-projects-to-improve-compilation.php}OK to leave projects open{adbe-popup} in the Navigator? |
| | * Notice the XML designator. |
| | * Use {adbe-popup:http://livedocs.adobe.com/flex/3/html/mxml_1.html}MXML{adbe-popup}to declare or create instances of Flex ActionScript Class components. |
| | |
| | {adbe-asp} |
| | h6. ASP |
| | |
| | * MXML files are [roughly equivalent to .aspx files.|Comparing ASP.NET and Flex development] |
| | {adbe-asp}{*}Key Concept*: [Designing a UI Layout|3c. Designing a UI - Layout] |
| | * Try out Flex components with the {adbe-popup:http://examples.adobe.com/flex3/componentexplorer/explorer.html}Flex Component Explorer.{adbe-popup} |
| | * See the {adbe-popup:http://livedocs.adobe.com/flex/3/langref/index.html}Flex ActionScript Language Reference.{adbe-popup} |
| | {adbe-pod} |
| | {column} |
| | {section} |
| | {section} |
| | {column:width=80%} |
| | |
| | h2. Create a bindable XML variable in ActionScript 3.0 |
| | |
| | 1. Before the HTTPService component, add a Script component by entering *<mx:Script>*. Flex Builder completes the tag for you. Alternatively, you can place the Script component after the HTTPService component. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | 2. In the mx:Script block, enter *import mx.collections.ArrayCollection*. ArrayCollection is the type of object that is used as a data provider. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | 3. After the ArrayCollection import statement, enter *import mx.rpc.events.ResultEvent* to import the ResultEvent class. The ResultEvent class is the type of event that the HTTPService generates. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | 4. Create a bindable *private* variable named *photoFeed* of the *ArrayCollection* class after the import statement in the mx:Script block. The photoFeed ArrayCollection is populated with the HTTPService response data. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | [Bindable] |
| | private var photoFeed:ArrayCollection; |
| | |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | {column} |
| | {column} |
| | {adbe-pod} |
| | |
| | h6. LEARN MORE |
| | |
| | * What is {adbe-popup:http://livedocs.adobe.com/flex/3/html/01_Introduction_2.html}ActionScript?{adbe-popup} |
| | {adbe-asp} |
| | h6. ASP |
| | |
| | * ActionScript files are roughly equivalent to [aspx.cs code behind files|What ASP.NET developers should know about Flex]. |
| | * How do I know {adbe-popup:http://livedocs.adobe.com/flex/3/html/usingas_2.html}when to use ActionScript and when to use MXML?{adbe-popup} |
| | {adbe-asp} |
| | * Learn about {adbe-popup:http://livedocs.adobe.com/flex/3/html/intro_workbench_3.html}Flex Builder code editor features{adbe-popup}. |
| | *Key Concept*: |
| | {adbe-popup:http://livedocs.adobe.com/flex/3/html/databinding_2.html#162751}Data Binding{adbe-popup} makes it easy to show and update data in the UI. When the data changes, the UI changes. |
| | {adbe-pod} |
| | {column} |
| | {section} |
| | {section} |
| | {column:width=80%} |
| | |
| | h2. Create the submit button click handler |
| | |
| | 1. Using the Outline view, locate the *Button* component in the *HBox* component. Clicking the Button component in the Outline view locates the Button component code in the Source mode. |
| | |
| | !outline1a.jpg! |
| | |
| | 2. To the Button component, add the *click* attribute with a value of *requestPhotos()*. When a user clicks the button, it calls the requestPhotos() handler, which initiates the HTTPService call. |
| | {code} |
| | <mx:Button label="Search" click="requestPhotos()"/> |
| | {code} |
| | |
| | h2. Send the HTTPService request and keywords to the Flickr API |
| | |
| | 3. Using the Outline view, locate the *TextInput* component in the *HBox* component and add the *id* attribute with a value of *searchTerms*. The instance name for the TextInput component is id. |
| | {code} |
| | <mx:TextInput id="searchTerms"/> |
| | {code} |
| | 4. In the mx:Script block, create a *private* function named *requestPhotos() with the return value of \*void*. This is the function where the HTTPService call is initiated. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | [Bindable] |
| | private var photoFeed:ArrayCollection; |
| | |
| | private function requestPhotos():void{ |
| | |
| | } |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | 5. In the function, cancel any previous requests to *photoService* by using the *cancel* method. The instance name of the HTTPService component is photoService. |
| | |
| | 6. Create an *Object* variable named *params.* |
| | |
| | 7. Create a *format* parameter of the *params* variable with a value of *rss_200_enc*. This value tells Flickr how to package the response. |
| | |
| | 8. Create a *tags* parameter of the *params* variable with a value of *searchTerms.text*. This is the value that was entered in the the search field. |
| | |
| | 9. Send the request and *params* by using the *send* method of *photoService*. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | [Bindable] |
| | private var photoFeed:ArrayCollection; |
| | |
| | private function requestPhotos():void{ |
| | photoService.cancel(); |
| | var params:Object = new Object(); |
| | params.format = 'rss_200_enc'; |
| | params.tags = searchTerms.text; |
| | photoService.send(params); |
| | } |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | {column} |
| | {column} |
| | {adbe-pod} |
| | |
| | h6. LEARN MORE |
| | |
| | *Key Concept:* |
| | \\ |
| | {adbe-popup:http://livedocs.adobe.com/flex/3/html/16_Event_handling_1.html}Event listeners and callback functions{adbe-popup} let your code respond to events, such as when the user clicks with a mouse. |
| | {adbe-pod} |
| | {column} |
| | {section} |
| | {section} |
| | {column:width=80%} |
| | |
| | h2. Create the HTTPService result handler |
| | |
| | 10. After the *requestPhotos()* function, create a *private* function named *photoHandler* and pass the *event* of type *ResultEvent* to the function. The return type is *void*. The photoHandler handles the response from the HTTPService call. |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | [Bindable] |
| | private var photoFeed:ArrayCollection; |
| | |
| | private function requestPhotos():void{ |
| | photoService.cancel(); |
| | var params:Object = new Object(); |
| | params.format = 'rss_200_enc'; |
| | params.tags = searchTerms.text; |
| | photoService.send(params); |
| | } |
| | |
| | private function photoHandler(event:ResultEvent):void{ |
| | |
| | } |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | |
| | h2. Populate the photoFeed XML variable |
| | |
| | 11. In the *photoHandler()* function, populate the *photoFeed* variable with the data located in the event object, *event.result.rss.channel.item,* and type it as *ArrayCollection* |
| | {code} |
| | <mx:Script> |
| | <![CDATA[ |
| | import mx.collections.ArrayCollection; |
| | import mx.rpc.events.ResultEvent; |
| | |
| | [Bindable] |
| | private var photoFeed:ArrayCollection; |
| | |
| | private function requestPhotos():void{ |
| | photoService.cancel(); |
| | var params:Object = new Object(); |
| | params.format = 'rss_200_enc'; |
| | params.tags = searchTerms.text; |
| | photoService.send(params); |
| | } |
| | |
| | private function photoHandler(event:ResultEvent):void{ |
| | photoFeed = event.result.rss.channel.item as ArrayCollection; |
| | } |
| | ]]> |
| | </mx:Script> |
| | {code} |
| | |
| | h2. Create the Tile component in MXML |
| | |
| | 1. Use a TileList component to display the images. After the *HBox* component and before the closing *Application* tag, add a *TileList* component with a *width* of *100%* and *height* of *100%*. |
| | {code} |
| | <mx:TileList width="100%" height="100%"> |
| | |
| | </mx:TileList> |
| | {code} |
| | |
| | h2. Bind the photoFeed XML data to the TileList component |
| | |
| | | 2. Using the *Outline* view, locate the *TileList* component and add an attribute of *dataProvider* with a value of \{photoFeed} to bind the data to the tile component. (Remember to move the > to the end of the new line) |
| | | 2. Using the *Outline* view, locate the *TileList* component and add an attribute of *dataProvider* with a value of \{photoFeed} to bind the data to the tile component. (Remember to move the > to the end of the dataProvider line.) |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | |
| | </mx:TileList> |
| | {code} |
| | |
| | h2. Create the thumbnails item renderer in the Tile component |
| | |
| | 3. The item renderer renders the layout for each item in the TileList. Within the *TileList* component, add a *itemRenderer* property. |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | <mx:itemRenderer> |
| | |
| | </mx:itemRenderer> |
| | </mx:TileList> |
| | {code} |
| | 4. Create a layout component for the item renderer. Within the *itemRenderer* property, add a *Component* component. |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | <mx:itemRenderer> |
| | <mx:Component> |
| | |
| | </mx:Component> |
| | </mx:itemRenderer> |
| | </mx:TileList> |
| | {code} |
| | 5. Create the layout the item renderer will use. Within the *Component*, add the *VBox* component with attributes of *width* with a value of *125*, *height* with a value of *125*. Add *paddingBottom, paddingTop, paddingRight* and *paddingLeft* each with a value of *5* |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | <mx:itemRenderer> |
| | <mx:Component> |
| | <mx:VBox width="125" height="125" |
| | paddingBottom="5" |
| | paddingLeft="5" |
| | paddingTop="5"> |
| | |
| | </mx:VBox> |
| | </mx:Component> |
| | </mx:itemRenderer> |
| | </mx:TileList> |
| | {code} |
| | 6. Within the *VBox* component, create a *Image* component. Add the attributes *width* with a *value* of *75*, *height* with a value of *75*. The itemRenderer passes values to the Image component through the Image component's data property. Add a *source* with a value of \{data.thumbnail.url} to the *Image* component to populate the image. |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | <mx:itemRenderer> |
| | <mx:Component> |
| | <mx:VBox width="125" height="125" |
| | paddingBottom="5" |
| | paddingLeft="5" |
| | paddingTop="5" |
| | paddingRight="5"> |
| | |
| | <mx:Image width="75" height="75" |
| | source="{data.thumbnail.url}"/> |
| | |
| | </mx:VBox> |
| | </mx:Component> |
| | </mx:itemRenderer> |
| | </mx:TileList> |
| | {code} |
| | 7. After the *Image* component, create a *Text* component with the *text* attribute having a value of \{data.credit} to display the name of the author. |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}"> |
| | <mx:itemRenderer> |
| | <mx:Component> |
| | <mx:VBox width="125" height="125" |
| | paddingBottom="5" |
| | paddingLeft="5" |
| | paddingTop="5" |
| | paddingRight="5"> |
| | |
| | <mx:Image width="75" height="75" |
| | source="{data.thumbnail.url}"/> |
| | |
| | <mx:Text text="{data.credit}"/> |
| | </mx:VBox> |
| | </mx:Component> |
| | </mx:itemRenderer> |
| | </mx:TileList> |
| | {code} |
| | 8. Save then run the application. You should see a form. Submit a search term. You should see the application display images. |
| | |
| | h2. Separate the thumbnail display to a custom component |
| | |
| | 9. Create a new component: *File > New > MXML Component*. |
| | # The filename is *FlickrThumbnail*. |
| | # The component is based on *VBox*. |
| | # Set the *width* to *125* and the *height* to *125*. |
| | |
| | 10. Using the *Outline* view, locate the *TileList* component. |
| | |
| | 11. Cut the *Image* and *Text* components from the *VBox* component in *TileList*, and paste them into *FlickrThumbnail.mxml*. |
| | {code} |
| | <?xml version="1.0" encoding="utf-8"?> |
| | <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" |
| | width="125" height="125"> |
| | |
| | <mx:Image width="75" height="75" |
| | source="{data.thumbnail.url}"/> |
| | |
| | <mx:Text text="{data.credit}"/> |
| | </mx:VBox> |
| | {code} |
| | 12. Add the following attributes to the VBox component: *paddingBottom*, *paddingTop*, *paddingRight*, and *paddingLeft* each with a value of *5*; *horizontalScrollPolicy* and *verticalScrollPolicy,* both with a value of *off*; and *horizontalAlign* with a value of *center*. |
| | {code} |
| | <?xml version="1.0" encoding="utf-8"?> |
| | <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" |
| | width="125" height="125" |
| | paddingBottom="5" paddingLeft="5" paddingTop="5" paddingRight="5" |
| | horizontalScrollPolicy="off" verticalScrollPolicy="off" |
| | horizontalAlign="center"> |
| | |
| | <mx:Image width="75" height="75" |
| | source="{data.thumbnail.url}"/> |
| | |
| | <mx:Text text="{data.credit}"/> |
| | </mx:VBox> |
| | {code} |
| | 13. Using the Outline view, locate the *TileList* component in the *FlickrRIA.mxml* template. |
| | |
| | 14. Delete the code for the *itemRenderer*, *Component,* and *VBox* components. |
| | |
| | 15. Add the attribute *itemRenderer* to the *TileList* component with a value of *FlickrThumbnail*. |
| | {code} |
| | <mx:TileList width="100%" height="100%" |
| | dataProvider="{photoFeed}" |
| | itemRenderer="FlickrThumbnail"> |
| | |
| | </mx:TileList> |
| | {code} |
| | 16. Compile and run the application. |
| | |
| | !final1.jpg! |
| | {column} |
| | {column} |
| | {column} |
| | {section} |
| | {adbe-prev:http://learn.adobe.com/wiki/display/Flex/1c.+Code+Anatomy} |
| | {adbe-next:http://learn.adobe.com/wiki/display/Flex/Part+II.+Exchanging+Data} |