SlideShare a Scribd company logo
Building (iPad) Apps with Flex



                    @danielwanja
                   http://n-so.com
Agenda


•   Flex SDK 4.6

•   Views and View Navigation

•   Components
Me
๏   d@n-so.com
                                      +
๏   @danielwanja
๏   n-so.com/blog
                                  =
๏   onrails.org
๏   appsden.com
๏   flexonrails.com
๏   github.com/danielwanja
Pinnacol -> Flex + Rails
Portfolio
Building iPad apps with Flex - 360Flex
My Own Stuff
And a book
github/danielwanja

•   activeresource - Flex to Ruby on Rails

•   talks/iPadAppsWithFlex - This talks and apps source code

•   TourDeMobileFlex - A demo of the Flex SDK

•   UndoManager - An experiment!
Flex and mobile?


•   Really?

•   Yea, Flex for Mobile rocks! Let’s check it out.

•   ...the good, the bad and the ugly!
Why should you listen?
Ways to build iOS apps


•   Native App - xCode

•   Hybrid App - PhoneGap, Titanium, ... others ... and Flex SDK

•   Mobile Web - HTML5, JavaScript, CSS
Why should you listen?


•   If you know Flex...it’s easy to get going with mobile
    development.

•   Flex = iOS, Android and more...
Tour De Mobile Flex Demo
Development Workflow

•   Desktop Emulator is fast

•   Nothing beats using the real thing. I use an Android Tablet to
    develop..

•   Unless you use the app on the Tablet...you won’t know if it’s
    right.
Development Workflow
•   FlashBuilder -> Debug/Run on Simulator
                 -> Debug/Run on Device (iOS no USB)


•   ADT -> Debug/Run on Simulator
        -> Debug/Run in iOS Emulator (XCode)
        -> Debug/Run on Device (wifi)
        -> Debug/Run on Device (usb)

•   Workflow is simpler with Android
FB: 3 templates (for now)
Blank App

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
	 	 	     xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
	 <fx:Declarations>
	 	 <!-- Place non-visual elements (e.g., services, value objects) here -->
	 </fx:Declarations>
</s:Application>
Blank App

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
	 	 	     xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
	 <s:layout>
	 	 <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
	 </s:layout>
	 <s:Label text="Welcome!" />
	 <s:DateSpinner />
</s:Application>
Blank App
ViewNavigatorApplication
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                            xmlns:s="library://ns.adobe.com/flex/spark"
                            firstView="views.RedView"
                            applicationDPI="160">
</s:ViewNavigatorApplication>




<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        title="Red View"
        backgroundColor="red">
</s:View>
navigator.pushView()

protected function showBlueClickHandler(event:MouseEvent):void
{
  var data:Object = null;
  var context:Object = null;
  var viewTransition:ViewTransitionBase = null;
  navigator.pushView(BlueView, data, context, viewTransition);
}
navigator.popView()

protected function goBackClickHandler(event:MouseEvent):void
{
  var viewTransition:ViewTransitionBase = null;
  navigator.popView(viewTransition);
}
ViewNavigator

•   pushView()

•   popView()

•   popToFirstView()

•   popAll()


                 app01_ViewNavigatorNavigation
TabbedViewNavigatorApplication


<s:TabbedViewNavigatorApplication>
  <s:ViewNavigator label="Red" width="100%" height="100%"
                   firstView="views.RedView"/>
  <s:ViewNavigator label="Green" width="100%" height="100%"
                   firstView="views.GreenView"/>
  <s:ViewNavigator label="Blue" width="100%" height="100%"
                   firstView="views.BlueView"/>
</s:TabbedViewNavigatorApplication>
ViewNavigator




<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
    <s:ViewNavigator   firstView="views.RedView" width="100%" height="100%"/>
</s:Application>
TabbedViewNavigator
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
    <s:TabbedViewNavigator width="100%" height="100%">
      <s:ViewNavigator label="Red" width="100%" height="100%"
                       firstView="views.RedView"/>
      <s:ViewNavigator label="Green" width="100%" height="100%"
                       firstView="views.GreenView"/>
      <s:ViewNavigator label="Blue" width="100%" height="100%"
                       firstView="views.BlueView"/>
    </s:TabbedViewNavigator>
</s:Application>
Anatomy of a Flex Mobile View
ActionBar



View Body
ActionBar


Navigation Content
                     Title Content
                                     Action Content
Navigation, Title, Action
•   actionBarVisible   •   navigationContent
•   actionContent      •   navigationLayout
•   actionLayout       •   overlayControls


•   title
                       •   viewMenuItems
•   titleContent
•   titleLayout
SplitViewNavigator
SplitViewNavigator

<s:SplitViewNavigator width="100%" height="100%">
  <s:ViewNavigator width="256" height="100%"
                    firstView="views.v03.MasterView" />
  <s:ViewNavigator id="mainNavigator" width="100%" height="100%"
                   firstView="views.v03.DetailView" />
</s:SplitViewNavigator>
Orientation Change




app04_OrientationChange.mxml
Orientation Change
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"
               resize="currentState = FlexGlobals.topLevelApplication.aspectRatio">
  <fx:Script>
      import mx.core.FlexGlobals;
  </fx:Script>
  <s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
  </s:states>	
  <s:layout>
    <s:HorizontalLayout verticalAlign="middle" horizontalAlign="center" />
  </s:layout>
  <s:Label text.landscape="LANDSCAPE" text.portrait="PORTRAIT" fontSize="120"/>
</s:Application>
Orientation Change
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"
               resize="currentState = FlexGlobals.topLevelApplication.aspectRatio">
  <fx:Script>
      import mx.core.FlexGlobals;
  </fx:Script>
  <s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
  </s:states>	
  <s:layout>
    <s:HorizontalLayout verticalAlign="middle" horizontalAlign="center" />
  </s:layout>
  <s:Label text.landscape="LANDSCAPE" text.portrait="PORTRAIT" fontSize="120"/>
</s:Application>
SplitViewNavigator
SplitViewNavigator
SplitViewNavigator




app03_SplitViewNavigatorHideLeftView
SplitViewNavigator
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:views="views.*"
               applicationDPI="160" >
  <views:SplitView width="100%" height="100%" />
</s:Application>
<s:SplitViewNavigator
  xmlns:fx="http://ns.adobe.com/mxml/2009"


                       SplitViewNavigator
  xmlns:s="library://ns.adobe.com/flex/spark"
  width="100%" height="100%"
  autoHideFirstViewNavigator="true"
  resize="currentState = FlexGlobals.topLevelApplication.aspectRatio">
  <s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
  </s:states>	
  <s:ViewNavigator width="256" height="100%" height.portrait="500"
firstView="views.RedView" />
  <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView"
>
    <s:navigationContent.portrait>
      <s:Button id="navigatorButton" label="Show Red"
                click="showFirstViewNavigatorInPopUp(navigatorButton)" />
    </s:navigationContent.portrait>
  </s:ViewNavigator>
  <fx:Script>
    import mx.core.FlexGlobals;
  </fx:Script>
</s:SplitViewNavigator>
<s:SplitViewNavigator
  xmlns:fx="http://ns.adobe.com/mxml/2009"


                       SplitViewNavigator
  xmlns:s="library://ns.adobe.com/flex/spark"
  width="100%" height="100%"
  autoHideFirstViewNavigator="true"
  resize="currentState = FlexGlobals.topLevelApplication.aspectRatio">
  <s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
  </s:states>	
  <s:ViewNavigator width="256" height="100%" height.portrait="500"
firstView="views.RedView" />
  <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView"
>
    <s:navigationContent.portrait>
      <s:Button id="navigatorButton" label="Show Red"
                click="showFirstViewNavigatorInPopUp(navigatorButton)" />
    </s:navigationContent.portrait>
  </s:ViewNavigator>
  <fx:Script>
    import mx.core.FlexGlobals;
  </fx:Script>
</s:SplitViewNavigator>
<s:SplitViewNavigator
  xmlns:fx="http://ns.adobe.com/mxml/2009"


                       SplitViewNavigator
  xmlns:s="library://ns.adobe.com/flex/spark"
  width="100%" height="100%"
  autoHideFirstViewNavigator="true"
  resize="currentState = FlexGlobals.topLevelApplication.aspectRatio">
  <s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
  </s:states>	
  <s:ViewNavigator width="256" height="100%" height.portrait="500"
firstView="views.RedView" />
  <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView"
>
    <s:navigationContent.portrait>
      <s:Button id="navigatorButton" label="Show Red"
                click="showFirstViewNavigatorInPopUp(navigatorButton)" />
    </s:navigationContent.portrait>
  </s:ViewNavigator>
  <fx:Script>
    import mx.core.FlexGlobals;
  </fx:Script>
</s:SplitViewNavigator>
Components

•   CalloutButton

•   DateSpinner

•   SpinnerList

•   ToggleSwitch

•   BusyIndicator
Flex SDK 4.6 Component
Recommend Components
                                 Spark Button
Spark ActionBar                  Spark CheckBox
Spark BusyIndicator              Spark DataGroup
Spark TabbedViewNavigator        Spark Group/HGroup/VGroup/TileGroup
Spark                            Spark Image/BitmapImage
TabbedViewNavigatorApplication   Spark Label
Spark View                       Spark List
Spark ViewMenu                   Spark RadioButton/RadioButtonGroup
Spark ViewNavigator
Spark ViewNavigatorApplication   Spark SkinnableContainer Spark Scroller
                                 Spark TextArea
                                 Spark TextInput
Discouraged Components

Spark DataGrid
Spark RichEditableText
Spark RichTex
CallOutButton




Image from http://devgirl.org/2011/10/17/flex-mobile-development-callout-component-sample-with-source/
CalloutButton

<s:CalloutButton id="callout" x="547" y="15" label="A Callout Button"
                 horizontalPosition="end" verticalPosition="after">
  <s:calloutLayout>
    <s:HorizontalLayout/>
 </s:calloutLayout>
  <s:Button label="Start" click="busy.visible=true; callout.closeDropDown();" />
  <s:Button label="Stop" click="busy.visible=false;callout.closeDropDown();" />
</s:CalloutButton>
DateSpinner




DATE (default)          TIME               DATE_AND_TIME

                 DateSelectorDisplayMode
DateSpinner

<s:DateSpinner displayMode="{dateDisplayMode.selectedItem.data}"   />

<s:DateSpinner displayMode="{DateSelectorDisplayMode.TIME}"   />

<s:DateSpinner displayMode="{DateSelectorDisplayMode.DATE_AND_TIME}"    />




       app20_DateSpinner
SpinnerList
SpinnerList
<s:SpinnerListContainer x="42" y="100" width="200" height="200">
  <s:SpinnerList id="spinnerList" height="100%" labelField="data">
    <s:ArrayList>
      <fx:Object data="data1"></fx:Object>
      <fx:Object data="data2"></fx:Object>
      <fx:Object data="data3"></fx:Object>
      <fx:Object data="data4"></fx:Object>
      <fx:Object data="data5"></fx:Object>
      <fx:Object data="data6"></fx:Object>
    </s:ArrayList>
  </s:SpinnerList>
</s:SpinnerListContainer>
SpinnerList
SpinnerList
<s:SpinnerListContainer top="350" left="100">
  <s:SpinnerList typicalItem="100">
    <s:dataProvider>
      <s:NumericDataProvider minimum="0" maximum="23" stepSize="1"/>
    </s:dataProvider>
  </s:SpinnerList>
  <s:SpinnerList typicalItem="100">
    <s:dataProvider>
      <s:NumericDataProvider minimum="0" maximum="59" stepSize="1"/>
    </s:dataProvider>
  </s:SpinnerList>
  <s:SpinnerList typicalItem="100"
                 dataProvider="{new ArrayList(['AM','PM'])}"
                 wrapElements="false"/>
</s:SpinnerListContainer>
SpinnerList + IconItemRenderer




  app21_IconSpinnerList
SpinnerList + IconItemRenderer
	   <fx:Declarations>
	   	 <s:ArrayCollection id="iconList">
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/flex_50x50.gif')" />
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/acrobat_50x50.gif')" />
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/flash-builder-48x48.png')" />
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/flash_50x50.gif')" />
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/flash_player_50x50.gif')" />
	   	 	 <fx:Object icon="@Embed('/assets/icons/spinner/photoshop_50x50.gif')" />
	   	 </s:ArrayCollection>	 	
	   </fx:Declarations>
SpinnerList + IconItemRenderer
	   <fx:Declarations>
	   	 <fx:Component className="CustomIconItemRenderer">
	   	 	 <s:IconItemRenderer labelField="" iconField="icon"/>
	   	 </fx:Component>	 	
	   </fx:Declarations>
	   <s:SpinnerListContainer>
	   	 <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="0"
	   	 	 	 	      itemRenderer="CustomIconItemRenderer" />
	   	 <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="2"
	   	 	 	 	      itemRenderer="CustomIconItemRenderer" />
	   	 <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="1"
	   	 	 	 	      itemRenderer="CustomIconItemRenderer" />
	   </s:SpinnerListContainer>
Keyboard




app10_keyboard
Keyboard
	   <s:TextInput   prompt="contact" 	 	 softKeyboardType="contact"/>
	   <s:TextInput   prompt="default" 	 	 softKeyboardType="default" />
	   <s:TextInput   prompt="email" 	 	    softKeyboardType="email"/>
	   <s:TextInput   prompt="number" 		    softKeyboardType="number"/>
	   <s:TextInput   prompt="punctuation" 	softKeyboardType="punctuation"/>




    default
Keyboard
	   <s:TextInput   prompt="contact" 	 	 softKeyboardType="contact"/>
	   <s:TextInput   prompt="default" 	 	 softKeyboardType="default" />
	   <s:TextInput   prompt="email" 	 	    softKeyboardType="email"/>
	   <s:TextInput   prompt="number" 		    softKeyboardType="number"/>
	   <s:TextInput   prompt="punctuation" 	softKeyboardType="punctuation"/>




    email
Keyboard
	    <s:TextInput   prompt="contact" 	 	 softKeyboardType="contact"/>
	    <s:TextInput   prompt="default" 	 	 softKeyboardType="default" />
	    <s:TextInput   prompt="email" 	 	    softKeyboardType="email"/>
	    <s:TextInput   prompt="number" 		    softKeyboardType="number"/>
	    <s:TextInput   prompt="punctuation" 	softKeyboardType="punctuation"/>




    number
Keyboard

<s:Application resizeForSoftKeyboard="true">


<s:Callout moveForSoftKeyboard="true">




          app10_keyboardAndPopup.mxml
          InputCallout.mxml
Keyboard Events


•   softKeyboardActivating

•   softKeyboardActivate

•   softKeyboardDeactivate
flash.ui.Multitouch.inputMode

•   MultitouchInputMode.NONE
    ➜ Mouse Events Only

•   MultitouchInputMode.TOUCH_POINT
    ➜ Mouse and Touch Events

•   MultitouchInputMode.GESTURE
    ➜ Mouse and Gesture Events
Touch Events
•   touchBegin
                               •   touchMove
•   touchDelay
                               •   touchOver
•   touchEnd
                               •   touchRollOut
•   touchInteractionEnd
                               •   touchRollOver
•   touchInteractionStart
                               •   touchTap
•   touchInteractionStarting

           app08_Touch.mxml
Touch Events
	   <s:Group width="100%" height="100%">
	   	 <s:touchBegin>
	   	 	 var id:int = event.touchPointID;   // to track multiple touchs at once
	   	 	 circle.x = event.localX - 70;
	   	 	 circle.y = event.localY - 70;
	   	 	 circle.visible = true;
	   	 </s:touchBegin>
	   	 <s:touchMove>
	   	 	 circle.x = event.localX - 70;
	   	 	 circle.y = event.localY - 70;
	   	 </s:touchMove>
	   	 <s:touchEnd>
	   	 	 circle.visible = false;
	   	 </s:touchEnd>
	   </s:Group>
Gestures
•   gesturePan

•   gesturePressAndTap

•   gestureRotate

•   gestureSwipe

•   gestureTwoFingerTap

•   gestureZoom

                                app09_Gestures.mxml
Gestures
	   <s:Group width="100%" height="100%">
	   	 <s:gesturePan>
	   	 	 img.x += event.offsetX;
	   	 	 img.y += event.offsetY;	 	 	 	
	   	 </s:gesturePan>
	   	 <s:gestureZoom>
	   	 	 img.transformAround(new Vector3D(event.localX, event.localY, 0),
	   	 	 	 	 	 	 	 new Vector3D(img.scaleX * event.scaleX,
                                   img.scaleY * event.scaleY, 0)
	   	 	 	 	 	 	 	 );
	   	 </s:gestureZoom>
	   	 <s:Image id="img" source="@Embed('/assets/apacheflex_fc.jpg')"/>
	   </s:Group>
Passing Data Around Views



•   ViewNavigator has build in mechanism to pass data to views

•   Each view has a data attribute



    app11_PassingData
Passing Data to a View
ListView                               DetailView




navigator.pushView(DetailView, list.selectedItem) ➡
Returning Data
DetailView                     SelectView


                pushView() ➡


                  popView()
Returning Data
                                 SelectView
                override public function createReturnObject():Object
popView() ➡     {	 	 	
                	 return selectedProduct;
                } 	



                                 DetailView        ➡
  <s:add>
  	 var returnedObject:ViewReturnObject = navigator.poppedViewReturnedObject;
  	 if (returnedObject&&returnedObject.object) {
  	 	 data.software = returnedObject.object;
  	 	 img.source = data.software.icon;
  	 }
  </s:add>
ItemRenderers


•   Performance issues with large list

•   Don’t use binding (for large list)



             app12_IconRenderer
ItemRenderers
	 <s:List width="100%" dataProvider="{data}" height="100%">
	 	 <s:itemRenderer>
	 	 	 <fx:Component>
	 	 	 	 <s:IconItemRenderer height="120" labelField="name"
	 	 	 	 	 	 	 	 	 iconField="photo" iconHeight="100" iconWidth="100"
	 	 	 	 	 	 	 	 	 messageFunction="getMessage"
	 	 	 	 	 	 	 	 	 decorator="@Embed('/assets/icons/twitter_icon_50.png')">
	 	 	 	 	 <fx:Script>
	 	 	 	 	 	 protected function getMessage(o:Object):String { return "@" +
o.thandle + " " + o.location; }
	 	 	 	 	 </fx:Script>
	 	 	 	 </s:IconItemRenderer>
	 	 	 </fx:Component>
	 	 </s:itemRenderer>	
	 </s:List>
Scroller

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
	 	 	     xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
	 <s:Scroller width="100%" height="100%">
	 	 <s:Group>
	 	 	 <s:Image source="@Embed('/assets/the_last_photo_of_the_eiffel_tower.jpg')"
	 	 	 	 	    width="5480" height="3596" />
	 	 </s:Group>	 	
	 </s:Scroller>
</s:Application>



                                                                app14_Scroller
StagedWebView
                     webView = new StageWebView();
                     webView.stage = this.stage;	 	
Creation Complete    resizeWebView();
                     webView.loadURL("http://google.com");	


                     var p:Point = new Point(0, 0);
                     p = this.localToGlobal(p);
           Resize    webView.viewPort = new Rectangle(p.x, p.y, this.width,
                     this.height);


                     var webView:StageWebView = this.webView;
         Remove      this.webView = null;	 	 	 	
                     webView.dispose();	

  app13_StageWebView
StageWebView
Additional Methods
webView.historyBack()
webView.historyForward()




Events
webView.addEventListener(Event.COMPLETE,handleLoad);
webView.addEventListener( LocationChangeEvent.LOCATION_CHANGING,
                          handleLocationChanging );
StageWebView
ActionScript to JavaScript Communication
webView.loadURL("javascript:alert('Flex talks to Javascript')");




JavaScript to ActionScript Communication

• less clean
• JavaScript sets document.location to pass some info as string
• Action use LocationChangeEvent, preventsDefault
•The reads the that info from event.location
Maps


•   Google Maps with StagedWebView

•   MapQuest Flex Components




app22_MapQuest
MapQuest
<tilemap:TilemapComponent id="map" width="100%"
height="100%" key="This%7IsCluu2n1uSecret-hw70u"
zoom="4"/>

geocoder = new Geocoder(map.tileMap);

map.addControl(new SMLargeZoomControl());
map.addControl(new SMViewControl());
map.addControl(new MouseWheelZoomControl());
http://developer.mapquest.com/web/products/featured/as3-flex-flash-mobile
MapQuest

geocoder.addEventListener(GeocoderEvent.GEOCODE_RESPONSE, onGeocodeResponse);
geocoder.addEventListener(GeocoderEvent.GEOCODE_ERROR_EVENT, onGeocodeError);
geocoder.addEventListener(GeocoderEvent.HTTP_ERROR_EVENT, this.onHttpError);



geocoder.geocode("Apple Store Aspen Grove, Littleton, CO");	
geocoder.geocode("10345 Park Meadows Drive, Lone Tree, CO");
mx:Chart
mx:Chart

[Bindable] private var serie:ArrayCollection = new ArrayCollection;

serie.addItem({rpm:rpm, response_time:run.last_response_time});
mx:Chart
<mx:LineChart id="chart" dataProvider="{serie}" showDataTips="true" >
	 <mx:verticalAxis>
	 	 <mx:LinearAxis id="vAxis"/>
	 </mx:verticalAxis>
	 <mx:series>
	 	 <mx:LineSeries yField="rpm">
	 	 	 <mx:fill>
	 	 	 	 <s:SolidColor color="#FF0000"/>
	 	 	 </mx:fill>
	 	 </mx:LineSeries>
	 </mx:series>
</mx:LineChart>
mx:Chart

<mx:ColumnChart id="chart2" dataProvider="{serie}" showDataTips="true">
	 <mx:verticalAxis>
	 	 <mx:LinearAxis id="vAxis2"/>
	 </mx:verticalAxis>
	 <mx:series>	 	
     <mx:ColumnSeries yField="response_time" />	
	 </mx:series>	 	
               	
</mx:ColumnChart>
References


•   DEVELOPING MOBILE APPLICATIONS WITH FLEX AND
    FLASH BUILDER 4.6
    http://help.adobe.com/en_US/flex/mobileapps/
    developing_mobile_apps_flex_4.6.pdf
Where we go from here?
•   2D

•   3D

•   Suite of Native Extensions



                     Go build stuff!
?
Swiz: initialize

	   	   <swiz:Swiz beanProviders="{[Config]}">
	   	   	 <swiz:config>
	   	   	 	 <swiz:SwizConfig strict="true"
	   	   	 	 	 	 	 	     eventPackages="events,flash.events"	 	 	 	 	 	
	   	   	 	 	 	 	 	     viewPackages="views"/>
	   	   	 </swiz:config>
	   	   </swiz:Swiz>
Swiz: config

<swiz:BeanProvider
	 xmlns:swiz="http://swiz.swizframework.org"
	 xmlns:fx="http://ns.adobe.com/mxml/2009"
	 xmlns:models="models.*"
	 xmlns:controllers="controllers.*"
	 >
	 <models:Model id="model" />	
	 <controllers:Controller id="controller" />
</swiz:BeanProvider>
Swiz: event


dispatchEvent(new SnapshotEvent(SnapshotEvent.TAKE, model.url,{width:300,
height:300}));
Swiz: controller

public class Controller
{
	 [Inject] public var model:Model;
	 	
	 	 [EventHandler(event='SnapshotEvent.TAKE', properties="url,data")]
	 	 public function takeSnapshot(url:String, data:Object):void {	 	 	
	 	 	 // do stuff
	 	 }
}
MORE STUFF...
ViewTransitionBase

•   CrossFadeViewTransition

•   FlipViewTransition

•   SlideViewTransition

•   ZoomViewTransition
Native Extension


•   For whatever need that is not fulfilled by the Flex SDK

•   Can include native Objective-C code with your App.

•   I.e.Vibration, Twitter integration, Game Center integration
Anatomic/Ergonomic/Physical
      Considerations
•   Hands are in the way

•   Looking down on table (viewing area)

•   Keyboard hides the bottom half of the screen...so don’t put
    input fields there (i.e. a filter at the bottom of a list)

•   ...
DPI: 160, 240, 360

•   Downscale .vs. Upscale conflicting approach (jpg/png .vs.
    vector graphics)

•   AIR 3.3, iOS SDK 5.1

•   override RuntimeDPIProvider

•   Set runtimeDPIProvider on your Application
Deploying Apps


•   iOS...arg! it’s slow...but works

•   Android...Yea!
Native Extension


•   Beyond the scope of this talk...It’s there and useful if you want
    to have functionality that’s not provided by the SDK
Building On The Command Line

•   compile    (mxml to swf)

•   package    (swf to ipa)

•   install app on iOS Simulator

•   launch app on IOS Simulator
Compile
$ mxmlc +configname=airmobile -compiler.library-path+=../libs -swf-version=16
                           myapp.mxml
Package for Simulator

adt -package -target ipa-test-interpreter-simulator -storetype pkcs12 -keystore
       cert.p12 -storepass secret myapp myapp.xml myapp.swf



                               ➜ myapp.ipa
Package for iPad

adt -package -target ipa-test -storetype pkcs12 -keystore cert.p12 -storepass a
   -provision.mobileprovision adt -package -target ipa-test -storetype pkcs12 -
  keystore cert.p12 -storepass a -provisioning-profile provision.mobileprovision
                        myapp myapp-app.xml myapp.swf


                               ➜ myapp.ipa
Move to iOS Simulator
     adt -installApp -platform ios -platformsdk /Developer/Platforms/
iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -device ios-
                       simulator -package myapp.ipa


     adt -launchApp -platform ios -platformsdk /Developer/Platforms/
iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -device ios-
                    simulator -appid com.n-so.myapp
Google Map


•   Use StageWebView

•   or use the e-skimo library




                    http://e-skimo.com/
Google Map
<pia:GMap id="map" width="100%" height="100%"
zoom="{zoomSlider.value}"
	 	    complete="map_completeHandler(event)"
	 	    error="SkinnableAlert.show(event.toString(),'Loading
Error')"/>


map.setCenter(39.545529,-104.87031);
map.zoom = 15;


map.addMarker(parseFloat(latMarker.text),parseFloat(lngMarker.text),
'360Flex','Custom description', true)

More Related Content

PDF
ARIA Gone Wild
PDF
Ionic by Example
PDF
IconFonts
PDF
Keyboard and Interaction Accessibility Techniques
PDF
Web Accessibility Gone Wild (Now Even MORE Wilder!)
PPTX
phonegap with angular js for freshers
TXT
Xxx
PDF
Bruce Lawson: Progressive Web Apps: the future of Apps
ARIA Gone Wild
Ionic by Example
IconFonts
Keyboard and Interaction Accessibility Techniques
Web Accessibility Gone Wild (Now Even MORE Wilder!)
phonegap with angular js for freshers
Xxx
Bruce Lawson: Progressive Web Apps: the future of Apps

What's hot (20)

PDF
Building Mobile Applications with Ionic
PDF
Mobile themes, QR codes, and shortURLs
PDF
jQuery Mobile and JavaScript
PPT
Mobile Information Architecture
PDF
HTML5 and CSS3 Shizzle
PPTX
Xaml novinky ve Windows 10
PDF
Joomla!Day 2013 Nürnberg; Vortrag von Johannes Hock
KEY
Really Rapid Admin Application Development
PPS
WPF (Windows Presentation Foundation Unit 01)
PPTX
Building jQuery Mobile Web Apps
PPTX
AppForum 2014 Boost Hybrid App Performance
PDF
HTML5 workshop, part 1
PDF
Applications: A Series of States
PDF
Programming with JavaFX
ODP
Passo a Passo para criar uma aplicação Móvel Híbrida
PDF
Win j svsphonegap-damyan-petev-mihail-mateev
PDF
Getting Started with DrupalGap
ODP
10 Things You're Not Doing [IBM Lotus Notes Domino Application Development]
PDF
Now you see me... Adaptive Web Design and Development
TXT
Teaching visual-symbols[1]
Building Mobile Applications with Ionic
Mobile themes, QR codes, and shortURLs
jQuery Mobile and JavaScript
Mobile Information Architecture
HTML5 and CSS3 Shizzle
Xaml novinky ve Windows 10
Joomla!Day 2013 Nürnberg; Vortrag von Johannes Hock
Really Rapid Admin Application Development
WPF (Windows Presentation Foundation Unit 01)
Building jQuery Mobile Web Apps
AppForum 2014 Boost Hybrid App Performance
HTML5 workshop, part 1
Applications: A Series of States
Programming with JavaFX
Passo a Passo para criar uma aplicação Móvel Híbrida
Win j svsphonegap-damyan-petev-mihail-mateev
Getting Started with DrupalGap
10 Things You're Not Doing [IBM Lotus Notes Domino Application Development]
Now you see me... Adaptive Web Design and Development
Teaching visual-symbols[1]
Ad

Similar to Building iPad apps with Flex - 360Flex (20)

PDF
Making mobile flex apps blazing fast
KEY
Mobile development with Flex 4.5 - LiveData May
PPT
Android Development with Flash Builder Burrito
PDF
Workshop 25: React Native - Components
PPTX
User experience and interactions design
PPT
Developing Mobile Applications using Flex 4.5
PPTX
Android 3
KEY
Introduction to Flex Hero for Mobile Devices
PDF
Adobe Flex - Developing Rich Internet Application Workshop Day 2
PPT
Getting the Magic on Android Tablets
PDF
Develop your first mobile App for iOS and Android
PDF
Develop your first mobile App for iOS and Android
KEY
Design Patterns for Tablets and Smartphones
PDF
##dd12 sviluppo mobile XPages
PPT
Adobe Flex Introduction
PDF
Mobile Apps Development Using Flash Builder 4.5
PPTX
The metro design language for app developers
PPTX
Material design
PDF
From iOS to Android
Making mobile flex apps blazing fast
Mobile development with Flex 4.5 - LiveData May
Android Development with Flash Builder Burrito
Workshop 25: React Native - Components
User experience and interactions design
Developing Mobile Applications using Flex 4.5
Android 3
Introduction to Flex Hero for Mobile Devices
Adobe Flex - Developing Rich Internet Application Workshop Day 2
Getting the Magic on Android Tablets
Develop your first mobile App for iOS and Android
Develop your first mobile App for iOS and Android
Design Patterns for Tablets and Smartphones
##dd12 sviluppo mobile XPages
Adobe Flex Introduction
Mobile Apps Development Using Flash Builder 4.5
The metro design language for app developers
Material design
From iOS to Android
Ad

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
sap open course for s4hana steps from ECC to s4
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Electronic commerce courselecture one. Pdf
PPTX
A Presentation on Artificial Intelligence
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Assigned Numbers - 2025 - Bluetooth® Document
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Machine learning based COVID-19 study performance prediction
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Cloud computing and distributed systems.
Spectral efficient network and resource selection model in 5G networks
Reach Out and Touch Someone: Haptics and Empathic Computing
NewMind AI Weekly Chronicles - August'25-Week II
sap open course for s4hana steps from ECC to s4
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Electronic commerce courselecture one. Pdf
A Presentation on Artificial Intelligence
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Assigned Numbers - 2025 - Bluetooth® Document
The AUB Centre for AI in Media Proposal.docx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Machine learning based COVID-19 study performance prediction
Per capita expenditure prediction using model stacking based on satellite ima...
MIND Revenue Release Quarter 2 2025 Press Release
“AI and Expert System Decision Support & Business Intelligence Systems”
MYSQL Presentation for SQL database connectivity
Cloud computing and distributed systems.

Building iPad apps with Flex - 360Flex

  • 1. Building (iPad) Apps with Flex @danielwanja http://n-so.com
  • 2. Agenda • Flex SDK 4.6 • Views and View Navigation • Components
  • 3. Me ๏ d@n-so.com + ๏ @danielwanja ๏ n-so.com/blog = ๏ onrails.org ๏ appsden.com ๏ flexonrails.com ๏ github.com/danielwanja
  • 9. github/danielwanja • activeresource - Flex to Ruby on Rails • talks/iPadAppsWithFlex - This talks and apps source code • TourDeMobileFlex - A demo of the Flex SDK • UndoManager - An experiment!
  • 10. Flex and mobile? • Really? • Yea, Flex for Mobile rocks! Let’s check it out. • ...the good, the bad and the ugly!
  • 11. Why should you listen?
  • 12. Ways to build iOS apps • Native App - xCode • Hybrid App - PhoneGap, Titanium, ... others ... and Flex SDK • Mobile Web - HTML5, JavaScript, CSS
  • 13. Why should you listen? • If you know Flex...it’s easy to get going with mobile development. • Flex = iOS, Android and more...
  • 14. Tour De Mobile Flex Demo
  • 15. Development Workflow • Desktop Emulator is fast • Nothing beats using the real thing. I use an Android Tablet to develop.. • Unless you use the app on the Tablet...you won’t know if it’s right.
  • 16. Development Workflow • FlashBuilder -> Debug/Run on Simulator -> Debug/Run on Device (iOS no USB) • ADT -> Debug/Run on Simulator -> Debug/Run in iOS Emulator (XCode) -> Debug/Run on Device (wifi) -> Debug/Run on Device (usb) • Workflow is simpler with Android
  • 17. FB: 3 templates (for now)
  • 18. Blank App <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> </s:Application>
  • 19. Blank App <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"> <s:layout> <s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/> </s:layout> <s:Label text="Welcome!" /> <s:DateSpinner /> </s:Application>
  • 21. ViewNavigatorApplication <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.RedView" applicationDPI="160"> </s:ViewNavigatorApplication> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Red View" backgroundColor="red"> </s:View>
  • 22. navigator.pushView() protected function showBlueClickHandler(event:MouseEvent):void { var data:Object = null; var context:Object = null; var viewTransition:ViewTransitionBase = null; navigator.pushView(BlueView, data, context, viewTransition); }
  • 23. navigator.popView() protected function goBackClickHandler(event:MouseEvent):void { var viewTransition:ViewTransitionBase = null; navigator.popView(viewTransition); }
  • 24. ViewNavigator • pushView() • popView() • popToFirstView() • popAll() app01_ViewNavigatorNavigation
  • 25. TabbedViewNavigatorApplication <s:TabbedViewNavigatorApplication> <s:ViewNavigator label="Red" width="100%" height="100%" firstView="views.RedView"/> <s:ViewNavigator label="Green" width="100%" height="100%" firstView="views.GreenView"/> <s:ViewNavigator label="Blue" width="100%" height="100%" firstView="views.BlueView"/> </s:TabbedViewNavigatorApplication>
  • 26. ViewNavigator <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"> <s:ViewNavigator firstView="views.RedView" width="100%" height="100%"/> </s:Application>
  • 27. TabbedViewNavigator <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"> <s:TabbedViewNavigator width="100%" height="100%"> <s:ViewNavigator label="Red" width="100%" height="100%" firstView="views.RedView"/> <s:ViewNavigator label="Green" width="100%" height="100%" firstView="views.GreenView"/> <s:ViewNavigator label="Blue" width="100%" height="100%" firstView="views.BlueView"/> </s:TabbedViewNavigator> </s:Application>
  • 28. Anatomy of a Flex Mobile View ActionBar View Body
  • 29. ActionBar Navigation Content Title Content Action Content
  • 30. Navigation, Title, Action • actionBarVisible • navigationContent • actionContent • navigationLayout • actionLayout • overlayControls • title • viewMenuItems • titleContent • titleLayout
  • 32. SplitViewNavigator <s:SplitViewNavigator width="100%" height="100%"> <s:ViewNavigator width="256" height="100%" firstView="views.v03.MasterView" /> <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.v03.DetailView" /> </s:SplitViewNavigator>
  • 34. Orientation Change <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160" resize="currentState = FlexGlobals.topLevelApplication.aspectRatio"> <fx:Script> import mx.core.FlexGlobals; </fx:Script> <s:states> <s:State name="portrait" /> <s:State name="landscape" /> </s:states> <s:layout> <s:HorizontalLayout verticalAlign="middle" horizontalAlign="center" /> </s:layout> <s:Label text.landscape="LANDSCAPE" text.portrait="PORTRAIT" fontSize="120"/> </s:Application>
  • 35. Orientation Change <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160" resize="currentState = FlexGlobals.topLevelApplication.aspectRatio"> <fx:Script> import mx.core.FlexGlobals; </fx:Script> <s:states> <s:State name="portrait" /> <s:State name="landscape" /> </s:states> <s:layout> <s:HorizontalLayout verticalAlign="middle" horizontalAlign="center" /> </s:layout> <s:Label text.landscape="LANDSCAPE" text.portrait="PORTRAIT" fontSize="120"/> </s:Application>
  • 39. SplitViewNavigator <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:views="views.*" applicationDPI="160" > <views:SplitView width="100%" height="100%" /> </s:Application>
  • 40. <s:SplitViewNavigator xmlns:fx="http://ns.adobe.com/mxml/2009" SplitViewNavigator xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%" autoHideFirstViewNavigator="true" resize="currentState = FlexGlobals.topLevelApplication.aspectRatio"> <s:states> <s:State name="portrait" /> <s:State name="landscape" /> </s:states> <s:ViewNavigator width="256" height="100%" height.portrait="500" firstView="views.RedView" /> <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView" > <s:navigationContent.portrait> <s:Button id="navigatorButton" label="Show Red" click="showFirstViewNavigatorInPopUp(navigatorButton)" /> </s:navigationContent.portrait> </s:ViewNavigator> <fx:Script> import mx.core.FlexGlobals; </fx:Script> </s:SplitViewNavigator>
  • 41. <s:SplitViewNavigator xmlns:fx="http://ns.adobe.com/mxml/2009" SplitViewNavigator xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%" autoHideFirstViewNavigator="true" resize="currentState = FlexGlobals.topLevelApplication.aspectRatio"> <s:states> <s:State name="portrait" /> <s:State name="landscape" /> </s:states> <s:ViewNavigator width="256" height="100%" height.portrait="500" firstView="views.RedView" /> <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView" > <s:navigationContent.portrait> <s:Button id="navigatorButton" label="Show Red" click="showFirstViewNavigatorInPopUp(navigatorButton)" /> </s:navigationContent.portrait> </s:ViewNavigator> <fx:Script> import mx.core.FlexGlobals; </fx:Script> </s:SplitViewNavigator>
  • 42. <s:SplitViewNavigator xmlns:fx="http://ns.adobe.com/mxml/2009" SplitViewNavigator xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%" autoHideFirstViewNavigator="true" resize="currentState = FlexGlobals.topLevelApplication.aspectRatio"> <s:states> <s:State name="portrait" /> <s:State name="landscape" /> </s:states> <s:ViewNavigator width="256" height="100%" height.portrait="500" firstView="views.RedView" /> <s:ViewNavigator id="mainNavigator" width="100%" height="100%" firstView="views.BlueView" > <s:navigationContent.portrait> <s:Button id="navigatorButton" label="Show Red" click="showFirstViewNavigatorInPopUp(navigatorButton)" /> </s:navigationContent.portrait> </s:ViewNavigator> <fx:Script> import mx.core.FlexGlobals; </fx:Script> </s:SplitViewNavigator>
  • 43. Components • CalloutButton • DateSpinner • SpinnerList • ToggleSwitch • BusyIndicator
  • 44. Flex SDK 4.6 Component
  • 45. Recommend Components Spark Button Spark ActionBar Spark CheckBox Spark BusyIndicator Spark DataGroup Spark TabbedViewNavigator Spark Group/HGroup/VGroup/TileGroup Spark Spark Image/BitmapImage TabbedViewNavigatorApplication Spark Label Spark View Spark List Spark ViewMenu Spark RadioButton/RadioButtonGroup Spark ViewNavigator Spark ViewNavigatorApplication Spark SkinnableContainer Spark Scroller Spark TextArea Spark TextInput
  • 46. Discouraged Components Spark DataGrid Spark RichEditableText Spark RichTex
  • 48. CalloutButton <s:CalloutButton id="callout" x="547" y="15" label="A Callout Button" horizontalPosition="end" verticalPosition="after"> <s:calloutLayout> <s:HorizontalLayout/> </s:calloutLayout> <s:Button label="Start" click="busy.visible=true; callout.closeDropDown();" /> <s:Button label="Stop" click="busy.visible=false;callout.closeDropDown();" /> </s:CalloutButton>
  • 49. DateSpinner DATE (default) TIME DATE_AND_TIME DateSelectorDisplayMode
  • 50. DateSpinner <s:DateSpinner displayMode="{dateDisplayMode.selectedItem.data}" /> <s:DateSpinner displayMode="{DateSelectorDisplayMode.TIME}" /> <s:DateSpinner displayMode="{DateSelectorDisplayMode.DATE_AND_TIME}" /> app20_DateSpinner
  • 52. SpinnerList <s:SpinnerListContainer x="42" y="100" width="200" height="200"> <s:SpinnerList id="spinnerList" height="100%" labelField="data"> <s:ArrayList> <fx:Object data="data1"></fx:Object> <fx:Object data="data2"></fx:Object> <fx:Object data="data3"></fx:Object> <fx:Object data="data4"></fx:Object> <fx:Object data="data5"></fx:Object> <fx:Object data="data6"></fx:Object> </s:ArrayList> </s:SpinnerList> </s:SpinnerListContainer>
  • 54. SpinnerList <s:SpinnerListContainer top="350" left="100"> <s:SpinnerList typicalItem="100"> <s:dataProvider> <s:NumericDataProvider minimum="0" maximum="23" stepSize="1"/> </s:dataProvider> </s:SpinnerList> <s:SpinnerList typicalItem="100"> <s:dataProvider> <s:NumericDataProvider minimum="0" maximum="59" stepSize="1"/> </s:dataProvider> </s:SpinnerList> <s:SpinnerList typicalItem="100" dataProvider="{new ArrayList(['AM','PM'])}" wrapElements="false"/> </s:SpinnerListContainer>
  • 55. SpinnerList + IconItemRenderer app21_IconSpinnerList
  • 56. SpinnerList + IconItemRenderer <fx:Declarations> <s:ArrayCollection id="iconList"> <fx:Object icon="@Embed('/assets/icons/spinner/flex_50x50.gif')" /> <fx:Object icon="@Embed('/assets/icons/spinner/acrobat_50x50.gif')" /> <fx:Object icon="@Embed('/assets/icons/spinner/flash-builder-48x48.png')" /> <fx:Object icon="@Embed('/assets/icons/spinner/flash_50x50.gif')" /> <fx:Object icon="@Embed('/assets/icons/spinner/flash_player_50x50.gif')" /> <fx:Object icon="@Embed('/assets/icons/spinner/photoshop_50x50.gif')" /> </s:ArrayCollection> </fx:Declarations>
  • 57. SpinnerList + IconItemRenderer <fx:Declarations> <fx:Component className="CustomIconItemRenderer"> <s:IconItemRenderer labelField="" iconField="icon"/> </fx:Component> </fx:Declarations> <s:SpinnerListContainer> <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="0" itemRenderer="CustomIconItemRenderer" /> <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="2" itemRenderer="CustomIconItemRenderer" /> <s:SpinnerList width="90" dataProvider="{iconList}" selectedIndex="1" itemRenderer="CustomIconItemRenderer" /> </s:SpinnerListContainer>
  • 59. Keyboard <s:TextInput prompt="contact" softKeyboardType="contact"/> <s:TextInput prompt="default" softKeyboardType="default" /> <s:TextInput prompt="email" softKeyboardType="email"/> <s:TextInput prompt="number" softKeyboardType="number"/> <s:TextInput prompt="punctuation" softKeyboardType="punctuation"/> default
  • 60. Keyboard <s:TextInput prompt="contact" softKeyboardType="contact"/> <s:TextInput prompt="default" softKeyboardType="default" /> <s:TextInput prompt="email" softKeyboardType="email"/> <s:TextInput prompt="number" softKeyboardType="number"/> <s:TextInput prompt="punctuation" softKeyboardType="punctuation"/> email
  • 61. Keyboard <s:TextInput prompt="contact" softKeyboardType="contact"/> <s:TextInput prompt="default" softKeyboardType="default" /> <s:TextInput prompt="email" softKeyboardType="email"/> <s:TextInput prompt="number" softKeyboardType="number"/> <s:TextInput prompt="punctuation" softKeyboardType="punctuation"/> number
  • 63. Keyboard Events • softKeyboardActivating • softKeyboardActivate • softKeyboardDeactivate
  • 64. flash.ui.Multitouch.inputMode • MultitouchInputMode.NONE ➜ Mouse Events Only • MultitouchInputMode.TOUCH_POINT ➜ Mouse and Touch Events • MultitouchInputMode.GESTURE ➜ Mouse and Gesture Events
  • 65. Touch Events • touchBegin • touchMove • touchDelay • touchOver • touchEnd • touchRollOut • touchInteractionEnd • touchRollOver • touchInteractionStart • touchTap • touchInteractionStarting app08_Touch.mxml
  • 66. Touch Events <s:Group width="100%" height="100%"> <s:touchBegin> var id:int = event.touchPointID; // to track multiple touchs at once circle.x = event.localX - 70; circle.y = event.localY - 70; circle.visible = true; </s:touchBegin> <s:touchMove> circle.x = event.localX - 70; circle.y = event.localY - 70; </s:touchMove> <s:touchEnd> circle.visible = false; </s:touchEnd> </s:Group>
  • 67. Gestures • gesturePan • gesturePressAndTap • gestureRotate • gestureSwipe • gestureTwoFingerTap • gestureZoom app09_Gestures.mxml
  • 68. Gestures <s:Group width="100%" height="100%"> <s:gesturePan> img.x += event.offsetX; img.y += event.offsetY; </s:gesturePan> <s:gestureZoom> img.transformAround(new Vector3D(event.localX, event.localY, 0), new Vector3D(img.scaleX * event.scaleX, img.scaleY * event.scaleY, 0) ); </s:gestureZoom> <s:Image id="img" source="@Embed('/assets/apacheflex_fc.jpg')"/> </s:Group>
  • 69. Passing Data Around Views • ViewNavigator has build in mechanism to pass data to views • Each view has a data attribute app11_PassingData
  • 70. Passing Data to a View ListView DetailView navigator.pushView(DetailView, list.selectedItem) ➡
  • 71. Returning Data DetailView SelectView pushView() ➡ popView()
  • 72. Returning Data SelectView override public function createReturnObject():Object popView() ➡ { return selectedProduct; } DetailView ➡ <s:add> var returnedObject:ViewReturnObject = navigator.poppedViewReturnedObject; if (returnedObject&&returnedObject.object) { data.software = returnedObject.object; img.source = data.software.icon; } </s:add>
  • 73. ItemRenderers • Performance issues with large list • Don’t use binding (for large list) app12_IconRenderer
  • 74. ItemRenderers <s:List width="100%" dataProvider="{data}" height="100%"> <s:itemRenderer> <fx:Component> <s:IconItemRenderer height="120" labelField="name" iconField="photo" iconHeight="100" iconWidth="100" messageFunction="getMessage" decorator="@Embed('/assets/icons/twitter_icon_50.png')"> <fx:Script> protected function getMessage(o:Object):String { return "@" + o.thandle + " " + o.location; } </fx:Script> </s:IconItemRenderer> </fx:Component> </s:itemRenderer> </s:List>
  • 75. Scroller <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"> <s:Scroller width="100%" height="100%"> <s:Group> <s:Image source="@Embed('/assets/the_last_photo_of_the_eiffel_tower.jpg')" width="5480" height="3596" /> </s:Group> </s:Scroller> </s:Application> app14_Scroller
  • 76. StagedWebView webView = new StageWebView(); webView.stage = this.stage; Creation Complete resizeWebView(); webView.loadURL("http://google.com"); var p:Point = new Point(0, 0); p = this.localToGlobal(p); Resize webView.viewPort = new Rectangle(p.x, p.y, this.width, this.height); var webView:StageWebView = this.webView; Remove this.webView = null; webView.dispose(); app13_StageWebView
  • 78. StageWebView ActionScript to JavaScript Communication webView.loadURL("javascript:alert('Flex talks to Javascript')"); JavaScript to ActionScript Communication • less clean • JavaScript sets document.location to pass some info as string • Action use LocationChangeEvent, preventsDefault •The reads the that info from event.location
  • 79. Maps • Google Maps with StagedWebView • MapQuest Flex Components app22_MapQuest
  • 80. MapQuest <tilemap:TilemapComponent id="map" width="100%" height="100%" key="This%7IsCluu2n1uSecret-hw70u" zoom="4"/> geocoder = new Geocoder(map.tileMap); map.addControl(new SMLargeZoomControl()); map.addControl(new SMViewControl()); map.addControl(new MouseWheelZoomControl()); http://developer.mapquest.com/web/products/featured/as3-flex-flash-mobile
  • 83. mx:Chart [Bindable] private var serie:ArrayCollection = new ArrayCollection; serie.addItem({rpm:rpm, response_time:run.last_response_time});
  • 84. mx:Chart <mx:LineChart id="chart" dataProvider="{serie}" showDataTips="true" > <mx:verticalAxis> <mx:LinearAxis id="vAxis"/> </mx:verticalAxis> <mx:series> <mx:LineSeries yField="rpm"> <mx:fill> <s:SolidColor color="#FF0000"/> </mx:fill> </mx:LineSeries> </mx:series> </mx:LineChart>
  • 85. mx:Chart <mx:ColumnChart id="chart2" dataProvider="{serie}" showDataTips="true"> <mx:verticalAxis> <mx:LinearAxis id="vAxis2"/> </mx:verticalAxis> <mx:series> <mx:ColumnSeries yField="response_time" /> </mx:series> </mx:ColumnChart>
  • 86. References • DEVELOPING MOBILE APPLICATIONS WITH FLEX AND FLASH BUILDER 4.6 http://help.adobe.com/en_US/flex/mobileapps/ developing_mobile_apps_flex_4.6.pdf
  • 87. Where we go from here? • 2D • 3D • Suite of Native Extensions Go build stuff!
  • 88. ?
  • 89. Swiz: initialize <swiz:Swiz beanProviders="{[Config]}"> <swiz:config> <swiz:SwizConfig strict="true" eventPackages="events,flash.events" viewPackages="views"/> </swiz:config> </swiz:Swiz>
  • 90. Swiz: config <swiz:BeanProvider xmlns:swiz="http://swiz.swizframework.org" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:models="models.*" xmlns:controllers="controllers.*" > <models:Model id="model" /> <controllers:Controller id="controller" /> </swiz:BeanProvider>
  • 92. Swiz: controller public class Controller { [Inject] public var model:Model; [EventHandler(event='SnapshotEvent.TAKE', properties="url,data")] public function takeSnapshot(url:String, data:Object):void { // do stuff } }
  • 94. ViewTransitionBase • CrossFadeViewTransition • FlipViewTransition • SlideViewTransition • ZoomViewTransition
  • 95. Native Extension • For whatever need that is not fulfilled by the Flex SDK • Can include native Objective-C code with your App. • I.e.Vibration, Twitter integration, Game Center integration
  • 96. Anatomic/Ergonomic/Physical Considerations • Hands are in the way • Looking down on table (viewing area) • Keyboard hides the bottom half of the screen...so don’t put input fields there (i.e. a filter at the bottom of a list) • ...
  • 97. DPI: 160, 240, 360 • Downscale .vs. Upscale conflicting approach (jpg/png .vs. vector graphics) • AIR 3.3, iOS SDK 5.1 • override RuntimeDPIProvider • Set runtimeDPIProvider on your Application
  • 98. Deploying Apps • iOS...arg! it’s slow...but works • Android...Yea!
  • 99. Native Extension • Beyond the scope of this talk...It’s there and useful if you want to have functionality that’s not provided by the SDK
  • 100. Building On The Command Line • compile (mxml to swf) • package (swf to ipa) • install app on iOS Simulator • launch app on IOS Simulator
  • 101. Compile $ mxmlc +configname=airmobile -compiler.library-path+=../libs -swf-version=16 myapp.mxml
  • 102. Package for Simulator adt -package -target ipa-test-interpreter-simulator -storetype pkcs12 -keystore cert.p12 -storepass secret myapp myapp.xml myapp.swf ➜ myapp.ipa
  • 103. Package for iPad adt -package -target ipa-test -storetype pkcs12 -keystore cert.p12 -storepass a -provision.mobileprovision adt -package -target ipa-test -storetype pkcs12 - keystore cert.p12 -storepass a -provisioning-profile provision.mobileprovision myapp myapp-app.xml myapp.swf ➜ myapp.ipa
  • 104. Move to iOS Simulator adt -installApp -platform ios -platformsdk /Developer/Platforms/ iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -device ios- simulator -package myapp.ipa adt -launchApp -platform ios -platformsdk /Developer/Platforms/ iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -device ios- simulator -appid com.n-so.myapp
  • 105. Google Map • Use StageWebView • or use the e-skimo library http://e-skimo.com/
  • 106. Google Map <pia:GMap id="map" width="100%" height="100%" zoom="{zoomSlider.value}" complete="map_completeHandler(event)" error="SkinnableAlert.show(event.toString(),'Loading Error')"/> map.setCenter(39.545529,-104.87031); map.zoom = 15; map.addMarker(parseFloat(latMarker.text),parseFloat(lngMarker.text), '360Flex','Custom description', true)