<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Designer - Defining the internet through beautiful design &#187; Adobe AIR</title>
	<atom:link href="http://www.webdesignermag.co.uk/category/tutorials/adobe-air-tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.webdesignermag.co.uk</link>
	<description>Web Design for real people</description>
	<lastBuildDate>Thu, 09 Feb 2012 01:00:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Build an Android App using Adobe AIR Pt.2</title>
		<link>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air-pt-2/</link>
		<comments>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air-pt-2/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 11:51:25 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=7472</guid>
		<description><![CDATA[Part Two of this tutorial looks at adding secondary-level views within an application to view specific content]]></description>
			<content:encoded><![CDATA[<!--android_logo--><!--codelibrary--><p><img class="alignnone size-full wp-image-7369" title="Build an Android App using Adobe AIR Pt.2" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/android_logo.jpg" alt="Build an Android App using Adobe AIR Pt.2" width="500" height="591" /></p>
<p>Developing a mobile application doesn’t need to be a scary procedure filled with insane logic and new languages to learn. Embrace your current ActionScript/AIR skills, whatever level they may be, and start developing for the next-generation of devices. Following on from <a title="Android Pt 1" href="http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air/" target="_self"><strong>part one</strong></a> of this tutorial in last month’s magazine, we will continue to work on our sample magazine issue application.<br />
Previously, we began our journey to create mobile content for the Android platform using Adobe AIR by creating our initial project in Flash Builder ‘Burrito’ and developing a simple layout, to allow us to retrieve dynamic data and to search using certain keywords.<br />
We’ll continue this month by adding a secondary view to the application, to allow users to drill down and view details on a specific issue selected from the list. This will be coupled with more interaction between the remote ColdFusion server to request information and obtain data.<br />
Finally, we’ll start to look at transferring the dynamic content to a remote server and the fantastic ability available within Flash Builder ‘Burrito’ to run and debug the application directly onto an Android device. Let’s get started…</p>
<p><strong>tools | tech | trends:</strong> Adobe AIR, Flash Builder Burrito, ColdFusion<br />
<strong>expert</strong>: Matt Gifford<br />
<strong>tutorial files:</strong> the full code can be <a href="http://www.webdesignermag.co.uk/tutorial-files/issue-181-tutorial-files/">downloaded here</a></p>
<p><strong>01. Create a view</strong><br />
Open up your MobileAIR project in Flash Builder ‘Burrito’, or import the .fxp file from the cover disc. From within the Package Explorer window, right-click on the Views folder and select New -&gt; MXML Component to create a new view component. Add the name ‘IssueDetail’ and accept the remaining default values to generate the new file.</p>
<p><strong>02. Pass information between views</strong><br />
The secondary view will display information for a specific issue once it has been selected from the list on the main page. Add a ‘change’ attribute to the List control to ‘push’ (or open) the new view onto the view stack. This function also passes the selected item so we can reference it.</p>
<p><em>&lt;s:List id=”IssueList” left=”0” right=”0”top=”73” bottom=”0”<br />
creationComplete=”list_creation CompleteHandler(event)”<br />
change=”navigator.pushView (IssueDetail,<br />
IssueList.selectedItem)”&gt;</em></p>
<p><strong>03. Configure Input Type</strong><br />
Open the ‘Data/Services’ panel and right-click the getIssueByID() method. Select ‘Configure Input Types’ from the context menu and select the required input type for the IssueID parameter to be an int. The getIssueByID() in our ColdFusion component expects a numeric argument, and this ensures the AIR application will expect the same.</p>
<p><strong>04. Get specific Issue data</strong><br />
Right-click the getIssueByID() method once more. Select Configure Return Type and choose the Auto-detect option. Enter an argument value of ‘1’ to test the returned data, and proceed to supply the name of ‘Issue’ for the data type. Click finish to complete the wizard. Right-click and select Generate Service call to create the required functions.</p>
<p><strong>05. Add viewActivate Handler</strong><br />
In Design View, highlight the View item within the window. Open the Properties tab and, within Alphabetical View, scroll down to click on ‘viewActivate’ from the list, which will generate the required functions and extra code for you. Replace the dummy text comment with the method to call the specific issue, casting the data.ID to the required int type.<br />
<em><br />
protected function view1_viewActivate Handler(event:FlexEvent):void<br />
{<br />
getIssueByID(data.ID as int);<br />
}</em></p>
<p><strong>06. Customise the View Title</strong><br />
Remote data results obtained by the IssueDetail component are now available to access through the ‘getIssueByIDResult’ responder id. In Source View, edit the title of the component to display the issue number of the specific issue selected by the user.</p>
<p><em>title=”Web Designer #{getIssueByIDResult.lastResult.ISSUENUMBER}”</em></p>
<p><strong>07. Add Back button</strong><br />
In IssueDetail.mxml, create an actionContent tag block. Inside this block, create a button with the ID ‘backBtn’ and a label of ‘Back’. This will have a click action, calling a function named ‘backBtn_clickHandler()’. This function will access the navigator instance, from which we will call the popToFirstView() method to remove all views from the stack except the very bottom one.</p>
<p><em>protected function backBtn_clickHandler(event:MouseEvent):void<br />
{<br />
navigator.popToFirstView();<br />
}</em></p>

					<div class="adInPost">
						<script type="text/javascript">
							GA_googleFillSlot("WD_MidPage_MPU1");
						</script>
					</div><p><strong>08. View the progress</strong><br />
Click the debug icon (the green insect) from the top menu to run the debugger. The Adobe Debugger Launcher (ADL) will open up over the workspace. Select an item from the list and click to be taken to the secondary view, now including the Back button and customised title bar. You can rotate the device using the ADL menu.</p>
<p><strong>09. Arrange the content</strong><br />
Add a VGroup component to the Source View, setting full width and height and 10 pixels padding on the left and right, into which we will place our text content. Wrap this VGroup inside a Scroller component, which will allow the user to scroll the content on this page if it exceeds the visible screen size.</p>
<p><em>&lt;s:Scroller width=”100%” height=”100%” top=”10”&gt;<br />
&lt;s:VGroup width=”100%” height=”100%” paddingLeft=”10” paddingRight=”10”&gt;<br />
&lt;!—Text fields will go here &#8211;&gt;<br />
&lt;/s:VGroup&gt;x<br />
&lt;/s:Scroller&gt;</em></p>
<p><strong>10. Display issue details</strong><br />
Add three labels and a TextArea component into the VGroup. Set the text attribute of the first label to “Release Date” and the font as bold. The second label will display dynamic data returned from the ColdFusion server, and so set the text attribute of this label to read {getIssueByIDResult.lastResult.RELEASEDATE}. Set the third label to “Features”.</p>
<p><em>&lt;s:Label fontWeight=”bold” paddingTop=”10” text=”Release Date”/&gt;<br />
&lt;s:Label width=”340” fontSize=”16” text=”{<br />
getIssueByIDResult.lastResult.<br />
RELEASEDATE}”/&gt;<br />
&lt;s:Label fontWeight=”bold” paddingTop=”10” text=”Features”/&gt;<br />
&lt;s:TextArea id=”htmlFeatures” width=”100%”  height=”100%” fontSize=”16” editable=”<br />
false” selectable=”false” /&gt;</em></p>
<p><strong>11. Convert the HTML</strong><br />
In order to display the content features in HTML format, we must import a MobileTextField class to set the htmlText display property of our TextArea component. Add the following code into the view1_viewActivateHandler function to set the HTML property. You also need to import the MobileTextField class.</p>
<p><em>import spark.components.supportClasses.MobileTextField;<br />
protected function view1_viewActivate Handler(event:FlexEvent):void<br />
{<br />
getIssueByID(data.ID as int); MobileText<br />
Field(htmlFeatures.textDisplay).htmlText =<br />
data.CONTENTFEATURES;<br />
}</em></p>
<p><strong>12. Get ColdFusion Hosting</strong><br />
To deploy and run the application on an Android device, you will need to transfer any code from the local ColdFusion server to a remote host, accessible from any network. www.hostmediauk.com offers ColdFusion 9 hosting on varying levels, from free to paid monthly services. Head over and create an account to get your own remote ColdFusion 9 hosting.</p>
<p><strong>13. Move to Live Server</strong><br />
Alternatively, you can use a remote server already created to test this application. Right-click the project, select Properties and choose Flex Server. Change the Root URL to http://labs.mattgifford.co.uk, where the remote services and assets have been set up for you. Open up MobileAIRHome.mxml and find the function called getIssueCover, and change the domain for the images to http://labs.mattgifford.co.uk.</p>
<p><strong>14. Change case</strong><br />
ActionScript is case-sensitive, and the results from the local environment are in uppercase, whereas data from the live server is not. Change any references of the data variables to the correct case before we test against the LIVE server to avoid any errors. Full code for this is available on the disc to assist you.</p>
<p><strong>15. Run on your device</strong><br />
Enable USB debugging on your Android device, and connect it to your machine. Select Run Configurations from the main menu (the drop-down next to the green Play button) and choose ‘On Device’. You may need Wi-Fi turned on to ensure connection speeds are okay. Flash Builder will compile the application, generating a .apk (Android package), and deploy it onto your device.</p>
<p><img class="alignnone size-full wp-image-7477" title="Build an Android App using Adobe AIR Pt.2" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/codelibrary.jpg" alt="Build an Android App using Adobe AIR Pt.2" width="549" height="498" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air-pt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build an Android App using Adobe AIR</title>
		<link>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air/</link>
		<comments>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 11:14:03 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[ColdFusion]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=7365</guid>
		<description><![CDATA[Part one of this tutorial looks at creating a layout for your app]]></description>
			<content:encoded><![CDATA[<!--android_logo--><!--step_01--><!--step_02--><!--step_03--><!--step_04--><!--step_05--><!--step_06--><!--step_07--><!--step_08--><!--step_09--><!--step_10--><!--step_11--><!--step_15--><p>Mobile development is rapidly becoming a requirement for the majority of web developers to consider. Clients may want an exceptional website, and a companion mobile application to allow their users and customers to use their services regardless of location. Typically, mobile app development brings with it a steep learning curve. With the latest release of Adobe’s Flash Builder tool, we are now able to develop for an Android device using familiar software and languages including ActionScript, and deploy as an AIR application.<br />
In part one of this tutorial, we will instal the required software and powerful server-side application to handle remote data connections, and produce a simple layout to display our dynamic data on an Android device. Next month we will enhance our mobile application with secondary views and built-in screen transitions.</p>
<p><strong>tools | tech | trends:</strong> Adobe AIR, Flash Builder Burrito, ColdFusion<br />
<strong>expert</strong>: Matt Gifford<br />
<strong>tutorial files:</strong> <a title="Tutorial files" href="http://www.webdesignermag.co.uk/tutorial-files/issue-180-tutorial-files/" target="_self">download here</a></p>
<p><img class="alignnone size-full wp-image-7369" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/android_logo.jpg" alt="Build an Android App using Adobe AIR" width="500" height="591" /></p>
<p><strong>01. Install ‘Burrito’</strong><br />
<img class="alignnone size-full wp-image-7370" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_01.jpg" alt="Build an Android App using Adobe AIR" width="500" height="327" /><br />
Firstly, download a copy of Adobe Flash Builder’s latest preview release, codenamed ‘Burrito’ from http://bit.ly/FlashBuilderBurrito. If you already own a copy of Flash Builder 4, your serial will work with this. If not, there is a 60-day trial for you to try out the software. Once downloaded, follow the installation wizard to install the application.</p>
<p><strong>02. Get ColdFusion</strong><br />
<img class="alignnone size-full wp-image-7371" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_02.jpg" alt="Build an Android App using Adobe AIR" width="500" height="334" /><br />
Now download ColdFusion 9 from http://adobe.ly/getColdFusion. Choose to download the free developer version from the right-hand menu and follow the installation wizard to install the server configuration version. A short video tutorial is also available to help you complete the installation process, which can be found at http://bit.ly/installColdFusion9.</p>
<p><strong>03. Add the datasource</strong><br />
<img class="alignnone size-full wp-image-7372" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_03.jpg" alt="Build an Android App using Adobe AIR" width="500" height="313" /><br />
Unzip database.zip from the disc and place the mobileDB directory in the ColdFusion db folder. In the Administrator (http://tinyurl.com/4x9s3j), navigate to Data &amp; Services&gt;Datasources and create a source called webDes_mobile with an Apache Derby Embedded driver. Set the database folder to the mobileDB folder.</p>
<p><strong>04. Copy files across</strong><br />
<img class="alignnone size-full wp-image-7373" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_04.jpg" alt="Build an Android App using Adobe AIR" width="500" height="245" /><br />
From the CD, open the ‘start/www’ folder and copy the files and directory structure into the ‘wwwroot’ folder within the ColdFusion directory. This contains the ColdFusion component (CFC) file that will interact as a gateway to query the database and send the recordset of data back to the mobile application.</p>
<p><strong>05. Create a project</strong><br />
<img class="alignnone size-full wp-image-7374" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_05.jpg" alt="Build an Android App using Adobe AIR" width="500" height="732" /><br />
In Flash Builder, click File&gt;New from the top menu and select Flex Mobile Project to create a new application skeleton. Enter the project name ‘MobileAIR’ and accept all default settings in this section and within the Mobile Settings window, which defines the basic settings for the mobile application layout.</p>
<p><strong>06. Configure Server Settings</strong><br />
<img class="alignnone size-full wp-image-7375" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_06.jpg" alt="Build an Android App using Adobe AIR" width="500" height="732" /><br />
In Server Settings, select ColdFusion from the list, and select ColdFusion Flash Remoting. Ensure the Standalone option is selected, and validate the configuration to connect to your ColdFusion install. The correct connection details can be found on the cover CD to help you. Click Finish to complete the set up.</p>
<p><strong>07. Setting the title</strong><br />
<img class="alignnone size-full wp-image-7376" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_07.jpg" alt="Build an Android App using Adobe AIR" width="500" height="313" /><br />
The project has been generated with two files open in Flash Builder. Close ‘MobileAIR.mxml’ as this file is a placeholder. ‘MobileAIRHome.mxml’ is the default view file and will contain the code for the layout. Click the Design button to go into Design View and change the title of the application to ‘Web Designer Issue List’.</p>
<p><strong>08. Add a list</strong><br />
<img class="alignnone size-full wp-image-7377" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_08.jpg" alt="Build an Android App using Adobe AIR" width="500" height="315" /><br />
To display a list of dynamic data, we can make use of the List control. Using the Components view, drag and drop a List control into the main area of the window, give it an ID of IssueList and set the constraints as zero all around except for a margin of 73 on the top, as shown in the screenshot.</p>

					<div class="adInPost">
						<script type="text/javascript">
							GA_googleFillSlot("WD_MidPage_MPU1");
						</script>
					</div><p><strong>09. Connect the data</strong><br />
<img class="alignnone size-full wp-image-7378" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_09.jpg" alt="Build an Android App using Adobe AIR" width="500" height="559" /><br />
Open the ‘Data/Services’ panel, click ‘Connect to Data/Service’ and select ColdFusion from the dialog window. On the next step browse to the location of the IssueService CFC file within the webroot. Enter the ColdFusion admin details if asked when proceeding to the next step. You’ll see a list of available remote methods usable within the application. Click Finish.</p>
<p><strong>10. Populate the list</strong><br />
<img class="alignnone size-full wp-image-7379" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_10.jpg" alt="Build an Android App using Adobe AIR" width="500" height="469" /><br />
Drag the getIssues() item from the panel onto the List control component to bind the remote data to it. Select ‘Configure Return Type’ and choose the ‘Auto-detect’ option before proceeding. Enter the custom name ‘Issues’ for the array to hold our dynamic data and finally choose IssueNumber as the label field option. Click OK to confirm the data binding.</p>
<p><strong>11. Test the dynamic data</strong><br />
<img class="alignnone size-full wp-image-7380" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_11.jpg" alt="Build an Android App using Adobe AIR" width="500" height="313" /><br />
Click the debug icon (the green insect) from the top menu to test the current implementation. The initial run will display a configuration window. Choose to launch the device from the desktop, and select an Android device to simulate from the drop-down list. The debugger will launch with the application and display the list of issue numbers as selectable buttons.</p>
<p><strong>12. Customise the list</strong><br />
Adding specific information to the list items is manageable by adding an custom itemRenderer property within the list tag block which will display an icon for each item listed. You can also set a labelFunction and messageFunction property which<br />
will display textual information about each magazine issue in the list. The full code for this step is included<br />
on the cover disc.</p>
<p><em>001 &lt;s:List id=”list” left=”0” right=”0”<br />
top=”73” bottom=”0”<br />
002     creationComplete=”list_creationComplete<br />
Handler(event)”&gt;<br />
003     &lt;s:AsyncListView list=”{getIssuesResult.<br />
lastResult}”/&gt;<br />
004     &lt;s:itemRenderer&gt;<br />
005         &lt;fx:Component&gt;<br />
006             &lt;s:MobileIconItemRenderer<br />
007                 iconHeight=”100” iconWidth=”100”<br />
008                 iconFunction=”getIssueCover”<br />
009                 labelFunction=”getIssueListTitle”<br />
010                 messageFunction=”getIssueKeywords”&gt;<br />
011<br />
012             &lt;/s:MobileIconItemRenderer&gt;<br />
013         &lt;/fx:Component&gt;<br />
014     &lt;/s:itemRenderer&gt;<br />
015 &lt;/s:List&gt;</em></p>
<p><strong>13.The display functions</strong><br />
The MobileIconItemRenderer class is expecting three functions to display the relevant content for each list item. Write these inside an fx:Script block and place them directly between the MobileIconItemRenderer tags to run in line for each item. The returned output from each function will be automatically displayed through the visual renderer component.</p>
<p><em>001 &lt;fx:Script&gt;<br />
002 &lt;![CDATA[<br />
003 private function getIssueCover(item:<br />
Object):String<br />
004 {<br />
005     return “http://localhost:8500/assets/<br />
coverImage/” + item.COVERIMAGE;<br />
006 }<br />
007 private function getIssueListTitle(item:<br />
Object):String<br />
008 {<br />
009     return “Web Designer “ + item.<br />
ISSUENUMBER;<br />
010 }<br />
011 private function getIssueKeywords(item:<br />
Object):String<br />
012 {<br />
013     return item.KEYWORDS;<br />
014 }<br />
015 ]]&gt;<br />
016 &lt;/fx:Script&gt;</em></p>
<p><strong>14. Adding search capabilities</strong><br />
In Design View, add a TextInput component above the list item with the ID ‘searchTxt’, setting both width and height to 100%. Add an event handler to run after pressing Enter which will call a performSearch() method and filter the results on a keyword search. Add the search function into the Code View inside the main script block. The full code for this step is on the disc.</p>
<p><em>001 protected function performSearch(event:<br />
Event):void<br />
002 {<br />
003     getIssuesResult.token = issueService.<br />
searchFeatures(searchTxt.text);<br />
004 }</em></p>
<p><strong>15. Run a search</strong><br />
<img class="alignnone size-full wp-image-7381" title="Build an Android App using Adobe AIR" src="http://www.webdesignermag.co.uk/wp-content/uploads/2011/10/step_15.jpg" alt="Build an Android App using Adobe AIR" width="500" height="313" /><br />
Run the debugger tool from the top menu to test the application. The list items now display custom info including images, and the search function updates the list using a filtered keyword search via ColdFusion. You can also use the debugger menu to rotate the device simulator to test horizontal and vertical displays.</p>
<p><span style="color: #888888;"><em><strong> LOOK OUT FOR PART TWO NEXT WEEK</strong></em></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/tutorials/build-an-android-app-using-adobe-air/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Develop an AIR Contact app in Flex Part 2</title>
		<link>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/</link>
		<comments>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 10:02:11 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=2846</guid>
		<description><![CDATA[STORE ALL YOUR FRIENDS' AND FAMILY'S CONTACT INFORMATION IN A USEFUL AIR APPLICATION]]></description>
			<content:encoded><![CDATA[<!--final--><p><a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/08/final.jpg"><img class="alignnone size-full wp-image-2852" title="Develop an AIR Contact app in Flex Part 2" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/08/final.jpg" alt="Develop an AIR Contact app in Flex Part 2" width="500" height="387" /></a></p>
<p>STORE ALL YOUR FRIENDS&#8217; AND FAMILY&#8217;S CONTACT INFORMATION IN A USEFUL AIR APPLICATION. LEARN HOW TO ADD, EDIT AND DELETE DATA IN AN SQLITE DATABASE IN PART 2 OF THIS TUTORIAL</p>
<p>In Part 1 we began coding an AIR contact manager with Flex and realised that the sheer amount of code meant we’d have to split it over two parts. So if you’re encountering this from scratch you’ll need to bear a couple of things in mind. Step 1 is in fact Step 16 in the overall tutorial. Find the code for <a href="http://www.webdesignermag.co.uk/tutorial-files/issue-146-tutorial-files/" target="_self">Part 2 here</a> and <a href="http://www.webdesignermag.co.uk/tutorial-files/issue-145-tutorial-files/" target="_self">Part 1 here</a></p>
<p><em><strong>Author: Simon Bailey | Originally appeared in Issue 146</strong></em><a href="http://www.webdesignermag.co.uk/tutorial-files/issue-145-tutorial-files/" target="_self"></a></p>
<p><strong>1 Instantiate SQLQueries</strong><br />
In ContactManager, navigate to the onOpen() method and enter the text below to create a new instance of the SQLQueries class. Using the instance of the LConnector class, parse the SQLConnection in the SQLQueries constructor and add an OnContacts method to the CONTACTS_ARR event, dispatching the ArrayCollection of contacts.</p>
<p><em>private function onOpen( e:Event ):void<br />
sqliteQueries = new SQLQueries( sqliteConnector.connection );<br />
sqliteQueries.addEventListener( SQLQueries.CONTACTS_ARR, onContacts );<br />
}<br />
private function onContacts( e:AllContactsEvent ):void<br />
{<br />
}</em></p>
<p><strong>2 Load contacts into wrapper</strong><br />
We need to parse the ArrayCollection of contacts to the ContactsWrapper. Enter the code below. Assign the contacts as the ContactList data grid’s data provider. In the onContacts() method in ContactManager, parse the contacts to  setContacts().</p>
<p><em>public function setContacts( contacts:ArrayCollection ):void{<br />
c_list.contact_dg.dataProvider = contacts;}<br />
private function onContacts( e:AllContactsEvent ):void{<br />
contactWrapper.setContacts( e.contacts );}</em></p>
<p><strong>3 Display contact<br />
</strong>In ContactWrapper, add a listener to the Select event on the ContactList component, calling a method named displayContact. The Contact variable is populated from the selectedContact reference assigned through mx:Binding in ContactList.</p>
<p><em>private function displayContact():void{<br />
c_details.add = false;<br />
c_details.edit = false;<br />
c_details.contact = c_list.selectedContact;<br />
}</em><strong></strong></p>
<p><strong>4 Add, edit, delete<br />
</strong>Still in the ContactWrapper class, enter the onClick() method. A switch statement analyses the eventName parsed and acts accordingly. Edit has two modes: edit, which transitions ContactDetails state, and save to retrieve edited contact details and saveContact().</p>
<p><em>private function onClick( eventName:String ):void<br />
{<br />
switch ( eventName )<br />
{<br />
case ‘edit’:<br />
if( !c_details.edit ){<br />
c_details.edit = true;<br />
}<br />
else<br />
{<br />
var contact:ContactVO = c_details.saveContact();<br />
( contact.firstName != “” ) ? saveContact( contact ) : c_details.clear();<br />
c_details.edit = false;<br />
}<br />
break;<br />
case ‘add’:<br />
c_details.edit = true;<br />
c_details.add = true;<br />
c_details.newContact();<br />
c_list.deSelect();<br />
break;<br />
case ‘delete’:<br />
if( c_list.contact_dg.selectedIndex != -1 ){<br />
c_list.deSelect();<br />
c_details.clear();</em><strong><br />
</strong><em>}<br />
break;<br />
}}</em><strong></strong></p>
<p><strong>5 saveContact<br />
</strong>If the contact has been edited, saveContact() is fired. This method expects a contact value object as its parameter and uses a custom event to dispatch the contact for storage. Add/edit is determined by the ContactDetails’ add Boolean.<strong></strong></p>

					<div class="adInPost">
						<script type="text/javascript">
							GA_googleFillSlot("WD_MidPage_MPU1");
						</script>
					</div><p><strong></strong><em>private function saveContact( contact:ContactVO ):void{<br />
if( !c_details.add ){<br />
}<br />
else<br />
{<br />
}<br />
}</em><strong><br />
</strong></p>
<p><strong>6 Creating custom events</strong><br />
We will create transparent background divs, with position: absolute set so they sit behind the content. Create the following class .background in the style sheet:<strong></strong></p>
<p><strong></strong><em>package events<br />
{<br />
import flash.events.Event;<br />
import vo.ContactVO;<br />
public class ContactEvent extends Event{<br />
public var contact:ContactVO;<br />
public function ContactEvent( _contact:ContactVO, type:String, bubbles:<br />
Boolean=false )<br />
{<br />
super( type, bubbles );<br />
this.contact = _contact;<br />
}<br />
public override function clone():Event<br />
{<br />
return new ContactEvent( contact, type, bubbles );<br />
}}}</em><strong></strong></p>
<p><strong>7 Overlaying content<br />
</strong>Create two new ActionScript classes that extend Event in the events directory named ‘ContactEvent’ and ‘AllContactsEvent’. These custom events will be used to dispatch a contact value object around our application and an ArrayCollection of contacts.</p>
<p><em>&lt;!&#8211; Dispatched Events &#8211;&gt;<br />
&lt;mx:Metadata&gt;<br />
[Event(name=”closeWin”, type=”flash.events.Event”)]<br />
[Event(name=”contactDelete”, type=”events.ContactEvent”)]<br />
[Event(name=”contactEdit”, type=”events.ContactEvent”)]<br />
[Event(name=”contactAdd”, type=”events.ContactEvent”)]<br />
&lt;/mx:Metadata&gt;<br />
// Dispatched events to add, edit and delete<br />
private static const CONTACT_DELETE:String = ‘contactDelete’;<br />
private static const CONTACT_EDIT:String = ‘contactEdit’;<br />
private static const CONTACT_ADD:String = ‘contactAdd’;<br />
case ‘delete’:<br />
if( c_list.contact_dg.selectedIndex != -1 ){<br />
var e:ContactEvent = new ContactEvent( c_list.selectedContact as ContactVO, CONTACT_<br />
DELETE, true );<br />
dispatchEvent( e );</em><strong><br />
</strong><em>c_list.deSelect();<br />
c_details.clear();<br />
}<br />
break;<br />
var e:ContactEvent;<br />
if( !c_details.add )<br />
{<br />
e = new ContactEvent( c_details.contact as ContactVO, CONTACT_EDIT, true );<br />
}<br />
else<br />
{<br />
e = new ContactEvent( c_details.contact as ContactVO, CONTACT_ADD, true );<br />
}<br />
dispatchEvent( e );</em><strong></strong></p>
<p><strong>8 Listen for custom events<br />
</strong>Edit the ContactWrapper component to listen for the dispatched custom events for Add,Edit and Delete. Create the three methods to handle the events and call the appropriate method in SQLQueries, parsing the contact value object stored in our custom event.<strong></strong></p>
<p><strong>/</strong><em>/ Add contact<br />
private function addContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.addContact( e.contact );<br />
}<br />
// Edit contact<br />
private function editContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.editContact( e.contact );<br />
}<br />
// Delete contact<br />
private function deleteContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.deleteContact( e.contact );<br />
}<br />
&lt;!&#8211; Contact Manager wrapper &#8211;&gt;<br />
&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0”<br />
closeWin=”closeWindow( event )”<br />
contactDelete=”deleteContact( event )”<br />
contactAdd=”addContact( event )”<br />
contactEdit=”editContact( event )” /&gt;</em><strong></strong></p>
<p><strong>9 Modification queries<br />
</strong>Add your final three methods to add, edit and delete data from our SQLite database.<strong></strong></p>
<p><strong></strong>// Edit a contact<br />
public function editContact( _contact:ContactVO ):void<br />
{<br />
var _sql:String = “UPDATE records SET firstName=:firstName, “ +<br />
“lastName=:lastName, “ +<br />
“email=:email, “ +<br />
“mobileTel=:mobileTel, “ +<br />
“homeTel=:homeTel, “ +<br />
“address=:address “ +<br />
“WHERE contactID=:contactID”;<br />
execute( _sql, contactResult, _contact, EDIT );<br />
}// Add a contact<br />
public function addContact( _contact:ContactVO ):void<br />
{<br />
var _sql:String = “INSERT INTO records (firstName, lastName, email, mobileTel,<br />
homeTel, address) “ +<br />
“VALUES (:firstName, :lastName, :email, :mobileTel, :homeTel, :address)”;<br />
execute( _sql, contactResult, _contact );<br />
}// Delete a contact<br />
public function deleteContact( _contact:ContactVO ):void{<br />
var _sql:String = “DELETE FROM records WHERE contactID=:contactID”;<br />
execute( _sql, contactResult, _contact, DELETE );}<br />
private function contactResult( e:SQLEvent ):void<br />
{<br />
getContacts();}}}<strong></strong></p>
<p><strong>10 Drag window<br />
</strong>Add a mouseDown Event Listener to the ContactWrapper instance, calling an onDrag() method. Within onDrag, call the startMove method on the NativeWindow class.<strong></strong></p>
<p><strong></strong><em>mouseDown=”onDrag( event )”<br />
// Enable drag of app<br />
private function onDrag(e:MouseEvent):void<br />
{<br />
stage.nativeWindow.startMove();<br />
}</em><strong></strong></p>
<p><strong>11 XML descriptor file<br />
</strong>Here you outline the application identifier, file name, description and window settings for display purposes.<strong><br />
</strong><em><br />
&lt;?xml version=”1.0” encoding=”UTF-8”?&gt;<br />
&lt;application xmlns=”http://ns.adobe.com/air/application/1.0”&gt;<br />
&lt;id&gt;ContactManager&lt;/id&gt;<br />
&lt;filename&gt;ContactManager&lt;/filename&gt;<br />
&lt;name&gt;Contact Manager&lt;/name&gt;<br />
&lt;version&gt;v1&lt;/version&gt;<br />
&lt;description&gt;Contact Manager application for managing all your friends and family<br />
contact information.&lt;/description&gt;<br />
&lt;initialWindow&gt;<br />
&lt;content&gt;[This value will be overwritten by Flex Builder in the<br />
output app.xml]&lt;/content&gt;<br />
&lt;title&gt;Contact Manager&lt;/title&gt;<br />
&lt;systemChrome&gt;none&lt;/systemChrome&gt;<br />
&lt;transparent&gt;false&lt;/transparent&gt;<br />
&lt;/initialWindow&gt;<br />
&lt;/application&gt;</em><strong></strong></p>
<p><strong>12 Test your app<br />
</strong>Click Run&gt;Run ContactManager, then click Add and add some contact information into the details panel. Click Save, test, edit and delete. Now click Project&gt;Export Release Build. Click Next&gt;Create to build a new digital certificate. Click Next and ensure the XML file, contacts database and SWF file are selected, then click Finish. Finally, double-click your newly created AIR file. Select Install, keep the next window’s defaults and select Continue.<strong></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Develop an AIR Contact app in Flex Part 1</title>
		<link>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/</link>
		<comments>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 09:57:03 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Contact Manager]]></category>
		<category><![CDATA[Flex Builder 3]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=2826</guid>
		<description><![CDATA[STORE ALL YOUR CONTACTS IN A USEFUL AIR APPLICATION BY LEARNING ADD, EDIT AND DELETE DATA TECHNIQUES WITHIN AN SQLITE DATABASE]]></description>
			<content:encoded><![CDATA[<!--final--><!--step1--><!--step2--><p><a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/final.jpg"><img class="alignnone size-full wp-image-2830" title="Develop an AIR Contact app in Flex Part 1" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/final.jpg" alt="Develop an AIR Contact app in Flex Part 1" width="500" height="385" /></a><br />
STORE ALL YOUR CONTACTS IN A USEFUL AIR APPLICATION BY LEARNING ADD, EDIT AND DELETE DATA TECHNIQUES WITHIN AN SQLITE DATABASE.</p>
<p>Developers can now take their RIA concepts out of the browser and onto the desktop. There are so many concepts feasible in an AIR application and with the ability to store data in a local database, programs we have long been familiar with can now be rebuilt with your own added flair. This tutorial will show you how to build a simplified version of Apple’s Address Book using SQLite to store contact information. The UI will be created using MXML components with ActionScript classes to control all functionality. We urposely aimed to use a variety of techniques in the code to handle states, communicate data, etc, so we would recommend studying the source for further insight. To complete this tutorial, you will need to use the source files to access all of the code; certain scripts are covered in each step. In addition, the guide is split over two parts with next month’s final text including the PDF pages and final files from here.</p>
<p><em><strong>Author: Simon Bailey | Originally appeared in Issue 146</strong></em></p>
<p><strong>01 Download required software</strong><br />
<a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step1.jpg"><img class="alignnone size-full wp-image-2831" title="Develop an AIR Contact app in Flex Part 1" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step1.jpg" alt="Develop an AIR Contact app in Flex Part 1" width="500" height="313" /></a><br />
Download the latest AIR runtime from http://get.adobe.com/air/ and follow the installation instructions provided by Adobe. If you do not have Flex Builder 3 installed, visit www.adobe.com/products/flex/ to download the 60-day free trial and install as instructed. Now we are ready to start setting up our project.</p>
<p><strong>02 New Flex project</strong><br />
<a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step2.jpg"><img class="alignnone size-full wp-image-2829" title="Develop an AIR Contact app in Flex Part 1" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step2.jpg" alt="Develop an AIR Contact app in Flex Part 1" width="500" height="448" /></a><br />
To fire up Flex, select File&gt;New&gt;Flex Project. Enter ‘ContactManager’ as the project name, check Default Location and check the Desktop application (runs in Adobe AIR). Ensure Application Server Type is set to None and click Next. Keep the default output folder and click Next, once again keeping all the defaults. Click Finish.</p>
<p><strong>03 Construct main component</strong><br />
Within the opening WindowedApplication tag in ContactManager.mxml, enter the code as below. Enter the second set of text above to set some basic styling for the contact manager. Create four new folders in the SRC directory: ‘components’, ‘events’, ‘SQLite’ and ‘VO’. Add the provided contacts database from the CD to the SRC folder.</p>
<p><em>&lt;mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
layout=”absolute”<br />
width=”450”<br />
height=”360”<br />
showFlexChrome=”false”<br />
verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”&gt;<br />
&lt;mx:Style&gt;<br />
TitleWindow<br />
{<br />
cornerRadius: 0;<br />
roundedBottomCorners: false;<br />
headerColors: #ffffff, #999999;<br />
footerColors: #cccccc, #999999;<br />
borderThicknessLeft: 0;<br />
borderThicknessTop: 0;<br />
borderThicknessBottom: 0;<br />
borderThicknessRight: 0;<br />
headerHeight: 34;<br />
shadowDistance: 0;<br />
dropShadowColor: #333333;<br />
titleStyleName: “contactTitle”;}<br />
.contactTitle<br />
{<br />
color: #333333;<br />
fontFamily: Verdana;<br />
fontSize: 12;<br />
fontWeight: bold;}<br />
&lt;/mx:Style&gt;</em></p>
<p><strong>04 Contact value object</strong><br />
Right-click the VO folder and create a new ActionScript class named ‘ContactVO’ and uncheck Generate constructor from superclass. Enter the code below. This custom value object will ensure correct data typing of contact details is used throughout this. The [Bindable] meta-data tag assigns instances of this class to MXML components.<br />
<em><br />
package vo<br />
{<br />
[Bindable]<br />
public class ContactVO<br />
{<br />
public var contactID:int;<br />
public var firstName:String;<br />
public var lastName:String;<br />
public var email:String;<br />
public var mobileTel:String;<br />
public var homeTel:String;<br />
public var address:String;<br />
public function ContactVO(){}<br />
}<br />
}</em></p>
<p><strong>05 Build a UI wrapper</strong><br />
Right-click the components folder, select New&gt;MXML Component. Set the file name as ‘ContactWrapper’ and base it on a TitleWindow. Clear width and height values and define layout as absolute. Within the opening TitleWindow tag, ensure the code is as below. Within the opening and closing TitleWindow tags, create a new &lt;mx:Script&gt; tag.</p>
<p><em>&lt;mx:TitleWindow xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*”<br />
layout=”absolute”<br />
title=”AIR Contact Manager”<br />
showCloseButton=”true”&gt;</em></p>
<p><strong>06 Add the wrapper</strong><br />
In ContactManager.mxml, ensure the code now looks like above. The main two changes here are a new XMLNS reference to our component’s directory so we can add the ContactWrapper component, which is near the bottom of the script. Next, we added an onCreationComplete method initApp() that runs when the component is fully created.</p>
<p><em>&lt;&lt;mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*” layout=”absolute”<br />
width=”450” height=”360”<br />
showFlexChrome=”false” verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”<br />
creationComplete=”initApp()”&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[private function initApp():void{}]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0” /&gt;</em></p>
<p><strong>07 Contact list</strong><br />
In the components folder, create a new MXML component extending Canvas named ‘ContactList’, adding the below code. This component will act as a simple list of all the contacts stored in our database. setName() concatenates the first and last name strings for display. &lt;mx:Binding&gt; binds items in the data grid to the variable selectedContact.</p>
<p><em>&lt;&lt;?xml version=”1.0” encoding=”utf-8”?&gt;<br />
&lt;mx:Canvas xmlns:mx=”http://www.adobe.com/2006/mxml”&gt;<br />
&lt;mx:Metadata&gt;<br />
[Event(name=”select”, type=”flash.events.Event”)]<br />
&lt;/mx:Metadata&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import mx.controls.dataGridClasses.DataGridColumn;<br />
import vo.ContactVO;<br />
public static const SELECT:String = ‘select’;<br />
[Bindable] public var selectedContact:ContactVO;<br />
private function setName( item:Object, column:DataGridColumn ):String<br />
{<br />
return String( item.firstName +” “+ item.lastName );}<br />
public function deSelect():void{<br />
contact_dg.selectedIndex = -1;}]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;mx:Binding source=”contact_dg.selectedItem as ContactVO” destina<br />
tion=”selectedContact”/&gt;<br />
&lt;mx:DataGrid id=”contact_dg” width=”100%” height=”100%”<br />
click=”if ( contact_dg.selectedIndex != -1) dispatchEvent(<br />
new Event( SELECT, true ) );”&gt;<br />
&lt;mx:columns&gt;<br />
&lt;mx:DataGridColumn labelFunction=”setName” headerText=”Name” /&gt;<br />
&lt;/mx:columns&gt;&lt;/mx:DataGrid&gt;&lt;/mx:Canvas&gt;</em><br />
<strong><br />
08 Contact details</strong><br />
In the components folder, create a new MXML component extending Canvas named ‘ContactDetails’, adding the below code. This displays all the contact data when selected in the ContactList. This component has two visual states, one to view the data and one to edit the data. State change is controlled by the Boolean variable ‘edit’.</p>
<p><em>i&lt;?xml version=”1.0” encoding=”utf-8”?&gt;<br />
&lt;mx:Canvas xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”<br />
currentState=”{ ( edit ) ? ‘edit_view’ : ‘’ }”&gt;<br />
&lt;mx:states&gt;<br />
&lt;mx:State name=”edit_view”&gt;<br />
&lt;mx:RemoveChild target=”{ first_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ last_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ email_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ mobile_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ home_txt }” /&gt;<br />
&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”first_in” text=”{ contact.firstName }” width=”95”<br />
x=”69” y=”10” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”last_in” text=”{ contact.lastName }” width=”95”<br />
x=”174” y=”10” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”email_in” text=”{ contact.email }” width=”200”<br />
x=”69” y=”50” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”mobile_in” text=”{ contact.mobileTel }” width=”200”<br />
x=”69” y=”90” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”home_in” text=”{ contact.homeTel }” width=”200”<br />
x=”69” y=”130” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;/mx:State&gt;&lt;/mx:states&gt;<br />
&lt;!&#8211; Transition for the screen &#8211;&gt;<br />
&lt;mx:transitions&gt;<br />
&lt;mx:Transition id=”fadeTransition” fromState=”*” toState=”*”&gt;<br />
&lt;mx:Parallel target=”{ this }”&gt;<br />
&lt;mx:Dissolve duration=”600”/&gt;<br />
&lt;/mx:Parallel&gt;&lt;/mx:Transition&gt;<br />
&lt;/mx:transitions&gt;<br />
&lt;!&#8211; First name &#8211;&gt;<br />
&lt;mx:Text id=”first_txt”<br />
text=”{ contact.firstName }” fontWeight=”bold”<br />
fontSize=”14” x=”66” y=”10”/&gt;<br />
&lt;!&#8211; Last name &#8211;&gt;<br />
&lt;mx:Text id=”last_txt”<br />
text=”{ contact.lastName }” fontWeight=”bold”<br />
fontSize=”14” x=”{ first_txt.x + first_txt.width + 3 }”<br />
y=”10”/&gt;<br />
&lt;!&#8211; Label = email &#8211;&gt;<br />
&lt;mx:Label text=”email”<br />
color=”#666666” fontSize=”12” x=”23” y=”50”/&gt;<br />
&lt;!&#8211; Label = mobile &#8211;&gt;<br />
&lt;mx:Label text=”mobile”<br />
color=”#666666” fontSize=”12”<br />
x=”15” y=”90”/&gt;<br />
&lt;!&#8211; Label = home &#8211;&gt;<br />
&lt;mx:Label text=”home”<br />
color=”#666666” fontSize=”12”<br />
x=”21” y=”130”/&gt;<br />
&lt;!&#8211; Label = address &#8211;&gt;</em></p>

					<div class="adInPost">
						<script type="text/javascript">
							GA_googleFillSlot("WD_MidPage_MPU1");
						</script>
					</div><p><em></em><strong>09 Populating contact details</strong><br />
Still in ContactDetails, enter the below code. Data will be parsed into this component as a custom contact value object, with each visual component referencing the object for data to display. To save the contact-edited information, the entered text in each TextInput component is assigned to its corresponding variable in the value object.<em></em></p>
<p><em>&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import vo.ContactVO;<br />
[Bindable] public var contact:ContactVO;<br />
[Bindable] public var edit:Boolean = false;<br />
public var add:Boolean;<br />
public function newContact():void{<br />
contact = new ContactVO();<br />
}<br />
public function saveContact():ContactVO<br />
{<br />
contact.firstName = first_in.text;<br />
contact.lastName = last_in.text;<br />
contact.email = email_in.text;<br />
contact.mobileTel = mobile_in.text;<br />
contact.homeTel = home_in.text;<br />
contact.address = address_txt.text;<br />
return contact;<br />
}<br />
public function clear():void<br />
{<br />
newContact();<br />
edit = false;<br />
}]]&gt;&lt;/mx:Script&gt;<br />
&lt;mx:Label text=”address”<br />
color=”#666666” fontSize=”12”<br />
x=”5” y=”170”/&gt;<br />
&lt;!&#8211; Email &#8211;&gt;<br />
&lt;mx:Text id=”email_txt”<br />
text=”{ contact.email }” color=”#000000”<br />
fontSize=”11” x=”66” y=”50”/&gt;<br />
&lt;!&#8211; Mobile &#8211;&gt;<br />
&lt;mx:Text id=”mobile_txt”<br />
text=”{ contact.mobileTel }”<br />
color=”#000000” fontSize=”11” x=”69” y=”91”/&gt;<br />
&lt;!&#8211; Home &#8211;&gt;<br />
&lt;mx:Text id=”home_txt”<br />
text=”{ contact.homeTel }” color=”#000000”<br />
fontSize=”11” x=”69” y=”131”/&gt;<br />
&lt;!&#8211; Address &#8211;&gt;<br />
&lt;mx:TextArea id=”address_txt”<br />
text=”{ contact.address }”<br />
color=”#000000” fontSize=”11” right=”40” left=”69”<br />
height=”90” borderThickness=”{ ( edit ) ? 1 : 0 }”<br />
wordWrap=”true” editable=”{ edit }” y=”171”/&gt;<br />
&lt;/mx:Canvas&gt;</em></p>
<p><strong>10 Add components to wrapper</strong><br />
Return to ContactWrapper and add the code below. Here we use the HDividedBox component to display our list and details custom components. This enables us to mimic Address Book and adjust the width of each component accordingly. A ControlBar is added to hold the buttons controlling the application’s add/edit and delete functionality.</p>
<p><em>&lt;!&#8211; Contact components container &#8211;&gt;<br />
&lt;mx:HDividedBox id=”contactContainer” x=”0” y=”0”<br />
width=”100%” height=”100%”&gt;<br />
&lt;view:ContactList id=”c_list” width=”30%” height=”100%” select=”displa<br />
yContact()” /&gt;<br />
&lt;view:ContactDetails id=”c_details” width=”70%” height=”100%” /&gt;<br />
&lt;/mx:HDividedBox&gt;<br />
&lt;mx:ControlBar id=”c_controls” width=”100%” height=”37” y=”229”&gt;<br />
&lt;mx:Button id=”addButton” height=”16” label=”add” click=”onClick(<br />
ADD )” x=”0”/&gt;<br />
&lt;mx:Button id=”deleteButton” height=”16” label=”delete”<br />
click=”onClick( DELETE )”/&gt;</em><br />
<em>&lt;mx:Spacer width=”{ c_details.width + c_list.width &#8211; (<br />
deleteButton.x + deleteButton.width + editButton.width + 20 ) }”/&gt;<br />
&lt;mx:Button id=”editButton” height=”16” label=”{ (c_details.edit ) ?<br />
‘save’ : ‘edit’ }”<br />
enabled=”{ c_details.edit || c_list.contact_dg.selectedIndex != -1<br />
}” click=”onClick( EDIT )”/&gt;&lt;/mx:ControlBar&gt;</em></p>
<p><strong>11 Handle window closure</strong><br />
TitleWindow has a close button available if showCloseButton is set as true. Enter the code below into the TitleWindow tag and within the mx:Script tags type: private static const CLOSE_WIN:String = ‘closeWin’. This will dispatch a named constant on clicking the close button. We will pick up this event in the ContactManager.</p>
<p><em>&lt;mx:TitleWindow xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*”<br />
layout=”absolute”<br />
title=”AIR Contact Manager”<br />
showCloseButton=”true”<br />
close=”{ dispatchEvent( new Event ( CLOSE_WIN ) ); }”&gt;</em></p>
<p><strong>12 Listen for close event</strong><br />
To listen out for the ContactWrapper dispatching our closeWin event modify the ContactWrapper tag as below and enter the closeWindow method within mx:Script tags. When the closeWin event is dispatched, the closeWindow method is fired calling the close() method in the NativeWindow class, and in turn closes the application window.</p>
<p><em>&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0”<br />
closeWin=”closeWindow( event )” /&gt;<br />
private function closeWindow( e:Event ):void{<br />
stage.nativeWindow.close();}</em></p>
<p><strong>13 Transparent backgrounds</strong><br />
Now we have the basic visual framework in place, let’s build our back-end. In the SQLite<br />
folder, create an ActionScript class to extend EventDispatcher named ‘SQLConnector’.<br />
This class will handle asynchronous connections to our SQLite database and dispatch<br />
SQLConnectionEvents for the application to progress and start querying the database.<br />
Enter the code as listed below:</p>
<p><em>package sqlite{<br />
import flash.data.SQLConnection;<br />
import flash.events.*;<br />
import flash.filesystem.File;<br />
public class SQLConnector extends EventDispatcher{<br />
public static const OPEN:String = ‘open’;<br />
public static const CLOSE:String = ‘close’;<br />
public static const ERROR:String = ‘error’;<br />
private var _connection:SQLConnection;<br />
private var _dbFileName:String;<br />
private var _dbFile:File;<br />
public function SQLConnector( name:String ){<br />
_dbFileName = name;<br />
_dbFile = File.applicationDirectory.resolvePath( _dbFileName );}<br />
public function connect():void{<br />
_connection = new SQLConnection();<br />
_connection.addEventListener( SQLEvent.OPEN, onOpen );<br />
_connection.addEventListener( SQLEvent.CLOSE, onClose );<br />
_connection.addEventListener( SQLErrorEvent.ERROR, onError );<br />
_connection.openAsync( _dbFile );}<br />
public function disconnect():void{<br />
_connection.close();}</em><br />
<em>public function get connection():SQLConnection{<br />
return _connection;}<br />
private function onOpen( e:SQLEvent ):void{<br />
dispatchEvent( new Event( OPEN ) );}<br />
private function onClose( e:SQLEvent ):void{<br />
dispatchEvent( new Event( CLOSE ) );}<br />
private function onError( e:SQLErrorEvent ):void{<br />
dispatchEvent( new Event( ERROR ) );<br />
}}}</em></p>
<p><strong>14 Set up connection</strong><br />
Return to the ContactManager and within the initApp() method, create a new instance of the SQLConnector ensuring that the class is imported. Parse in the constructor the named constant that has the database name as a ‘String’ and call the Connect method. Assign listeners for all class-dispatched events: OPEN, CLOSE and ERROR.</p>
<p><em>import sqlite.SQLConnector;<br />
private static const DATABASE:String = “contacts”;<br />
private function initApp():void<br />
{<br />
sqliteConnector = new SQLConnector( DATABASE );<br />
sqliteConnector.connect();<br />
sqliteConnector.addEventListener( SQLConnector.OPEN, onOpen );<br />
sqliteConnector.addEventListener( SQLConnector.CLOSE, onClose );<br />
sqliteConnector.addEventListener( SQLConnector.ERROR, onError );}<br />
private function onOpen( e:Event ):void<br />
{<br />
}<br />
private function onClose( e:Event ):void{<br />
trace(“disconnection”);<br />
}<br />
private function onError( e:Event ):void{<br />
trace(“connection error”);<br />
}</em></p>
<p><strong>15 Start querying</strong><br />
In the SQLite folder, create an ActionScript class to extend EventDispatcher named ‘SQLQueries’. This class will handle all the database queries and dispatch results for each query made. This class needs a reference to the SQLConnection, adds, edits and deletes, and has a method to build the table ‘records’ in the database.</p>
<p><em>package sqlite<br />
{<br />
import events.AllContactsEvent;<br />
import flash.data.*;<br />
import flash.errors.SQLError;<br />
import flash.events.*;<br />
import mx.collections.ArrayCollection;<br />
import vo.ContactVO;<br />
public class SQLQueries extends EventDispatcher{<br />
public static const CONTACTS_ARR:String = ‘contactsArr’;<br />
private static const EDIT:String = ‘edit’;<br />
private static const DELETE:String = ‘delete’;<br />
private var _connection:SQLConnection;<br />
private var _statement:SQLStatement;<br />
private var _data:ArrayCollection;<br />
public function SQLQueries( conn:SQLConnection ){<br />
_connection = conn;<br />
buildTable();}<br />
private function buildTable():void{<br />
var _sql:String = “CREATE TABLE IF NOT EXISTS records ( contactID<br />
INTEGER PRIMARY KEY AUTOINCREMENT, “ +</em><br />
<em>“firstName TEXT DEFAULT ‘’, “ +<br />
“lastName TEXT DEFAULT ‘’, “ +<br />
“email TEXT DEFAULT ‘’, “ +<br />
“mobileTel TEXT DEFAULT ‘’, “ +<br />
“homeTel TEXT DEFAULT ‘’, “ +<br />
“address TEXT DEFAULT ‘’)”;<br />
execute( _sql, buildTableResult );}<br />
public function getContacts():void{<br />
var _sql:String = “SELECT * FROM records”;<br />
execute( _sql, getContactsResult );<br />
}<br />
private function execute( sql:String, _handler:<br />
Function, params:ContactVO=null, action:String=”” ):void{<br />
try<br />
{<br />
var handler:Function = _handler;<br />
_statement = new SQLStatement();<br />
_statement.sqlConnection = _connection;<br />
_statement.text = sql;<br />
if( params )<br />
{<br />
_statement.clearParameters();<br />
if( action != “” ){<br />
_statement.parameters[“:contactID”] = params.contactID;}<br />
if( action != DELETE ){<br />
_statement.parameters[“:firstName”] = params.firstName;<br />
_statement.parameters[“:lastName”] = params.lastName;<br />
_statement.parameters[“:email”] = params.email;<br />
_statement.parameters[“:mobileTel”] = params.mobileTel;<br />
_statement.parameters[“:homeTel”] = params.homeTel;<br />
_statement.parameters[“:address”] = params.address;}}<br />
_statement.addEventListener( SQLEvent.RESULT, handler );<br />
_statement.execute();<br />
}<br />
catch ( e:SQLError )<br />
{<br />
trace(“Error with SQLStatement execution”);<br />
}}<br />
private function buildTableResult( e:SQLEvent ):void{<br />
getContacts();}<br />
private function getContactsResult( e:SQLEvent ):void{<br />
var contacts:ArrayCollection = new ArrayCollection();<br />
for each ( var c:Object in _statement.getResult().data ){<br />
var contact:ContactVO = new ContactVO();<br />
contact.contactID = c.contactID;<br />
contact.firstName = c.firstName;<br />
contact.lastName = c.lastName;<br />
contact.email = c.email;<br />
contact.mobileTel = c.mobileTel;<br />
contact.homeTel = c.homeTel;<br />
contact.address = c.address;<br />
contacts.addItem( contact );}<br />
var event:AllContactsEvent = new AllContactsEvent( contacts,<br />
CONTACTS_ARR, true );<br />
dispatchEvent( event );}}}<br />
</em></p>
<p><strong>The code marathon continues in Part 2 &#8211; coming soon</strong><em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

