SlideShare a Scribd company logo
1 of 106
Download to read offline
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
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

What's hot

Win j svsphonegap-damyan-petev-mihail-mateev
Win j svsphonegap-damyan-petev-mihail-mateevWin j svsphonegap-damyan-petev-mihail-mateev
Win j svsphonegap-damyan-petev-mihail-mateev
Mihail Mateev
 
Teaching visual-symbols[1]
Teaching visual-symbols[1]Teaching visual-symbols[1]
Teaching visual-symbols[1]
Ecinue03
 

What's hot (20)

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

Similar to Building iPad apps with Flex - 360Flex

Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Atlassian
 
Web app and more
Web app and moreWeb app and more
Web app and more
faming su
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
Anton Narusberg
 

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

Android Workshop
Android WorkshopAndroid Workshop
Android Workshop
 
Multi screen HTML5
Multi screen HTML5Multi screen HTML5
Multi screen HTML5
 
Once Source to Rule Them All
Once Source to Rule Them AllOnce Source to Rule Them All
Once Source to Rule Them All
 
Taking your Web App for a walk
Taking your Web App for a walkTaking your Web App for a walk
Taking your Web App for a walk
 
Introduction to Palm's Mojo SDK
Introduction to Palm's Mojo SDKIntroduction to Palm's Mojo SDK
Introduction to Palm's Mojo SDK
 
Mobile Web Development
Mobile Web DevelopmentMobile Web Development
Mobile Web Development
 
Responsive design
Responsive designResponsive design
Responsive design
 
HTML5 on Mobile
HTML5 on MobileHTML5 on Mobile
HTML5 on Mobile
 
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012 Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
Plugins on OnDemand with Remote Apps - Atlassian Summit 2012
 
Web Development for UX Designers
Web Development for UX DesignersWeb Development for UX Designers
Web Development for UX Designers
 
ADF Mobile: 10 Things you don't get from the developers guide - Luc Bors
ADF Mobile: 10 Things you don't get from the developers guide - Luc BorsADF Mobile: 10 Things you don't get from the developers guide - Luc Bors
ADF Mobile: 10 Things you don't get from the developers guide - Luc Bors
 
ADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guideADF Mobile: 10 Things you don't get from the developers guide
ADF Mobile: 10 Things you don't get from the developers guide
 
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
 
Responsive Websites
Responsive WebsitesResponsive Websites
Responsive Websites
 
Web Apps and more
Web Apps and moreWeb Apps and more
Web Apps and more
 
Web app and more
Web app and moreWeb app and more
Web app and more
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Apps
 
amis-adf-enterprise-mobility
amis-adf-enterprise-mobilityamis-adf-enterprise-mobility
amis-adf-enterprise-mobility
 
Android JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerAndroid JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation Controller
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

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
  • 6.
  • 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)