Flex Mobile Development – SplitViewNavigator Tutorial (w/ source)

December 1, 2011By 37 Comments

The SplitViewNavigator is another new Flex 4.6 component targeted for tablet development that can be used when you want to create a master view / detail view in your application, where the master view typically serves as a source of navigation and the detail view displays the results of the action taken on the master view. The master view is typically the left or top of the screen, and the detail view is typically the right side or bottom part of the screen depending on layout. If you’re not familiar with this screen pattern, see this link for more detail. A great example of this is your typical mail application, for instance on one of my iPad email accounts:

Now we can build applications with this type of layout simply using built-in Flex 4.6 features! The SplitViewNavigator extends ViewNavigatorBase, so it does not reside at the root level of the application but rather at the child level similar to ViewNavigator. Note that this component can only be used in a blank Application or within a TabbedViewNavigatorApplication. Here’s an example:

<?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">
	
	<s:SplitViewNavigator id="svn" width="100%" height="100%">
		<s:ViewNavigator id="leftNav" width="30%" height="100%" firstView="views.LeftView"/>
		<s:ViewNavigator id="rightNav" width="100%" height="100%" firstView="views.RightView"/>
	</s:SplitViewNavigator>
</s:Application>

In this case my left view and right view are simple View classes showing a list of cities to click on and some dummy data about that particular city in the detail. I’ve included the code below for reference:

LeftView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" title="Left View">
	
	<fx:Script>
		<![CDATA[
			protected function list_clickHandler(event:MouseEvent):void
			{
				(this.parentDocument as Sample).rightNav.activeView.data=list.selectedItem;
			}			
		]]>
	</fx:Script>
	
	<s:List id="list" width="100%" height="100%" click="list_clickHandler(event)">
		<s:dataProvider>
			<s:ArrayCollection>
				<fx:String>Atlanta, GA</fx:String>
				<fx:String>Baltimore, MD</fx:String>
				<fx:String>Boston, MA</fx:String>
				<fx:String>Chicago, IL</fx:String>
				<fx:String>Dallas, TX</fx:String>
				<fx:String>Detroit, MI</fx:String>
				<fx:String>Honolulu, HI</fx:String>
				<fx:String>Los Angeles, CA</fx:String>
				<fx:String>Minneapolis, MA</fx:String>
				<fx:String>New Orleans, LA</fx:String>
				<fx:String>New York, NY</fx:String>
				<fx:String>Richmond, VA</fx:String>
				<fx:String>San Francisco, CA</fx:String>
				<fx:String>San Jose, CA</fx:String>
				<fx:String>St. Louis, MO</fx:String>
				<fx:String>Washington, DC</fx:String>
			</s:ArrayCollection>
		</s:dataProvider>
	</s:List>
</s:View>

RightView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Detail View">
	<s:layout>
		<s:VerticalLayout paddingTop="15" paddingBottom="15" paddingLeft="15" paddingRight="15" gap="5" 
						  horizontalAlign="center" verticalAlign="top"/>
	</s:layout>
	<s:Label text="Click on a location on the left to explore!" visible="{data==null?true:false}"/>
	<s:Label text="Information about {this.data}" visible="{data!=null?true:false}"/>
	
	<s:TextArea text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur accumsan felis ac tortor aliquam iaculis. Phasellus hendrerit viverra enim, sit amet scelerisque lectus dictum at. Aenean sodales nisi sed leo congue et porttitor ligula vehicula. 
Pellentesque turpis massa, suscipit vel fermentum quis, dignissim sed ipsum. Nulla aliquet libero adipiscing risus lobortis eleifend quis at velit. Duis at leo urna. 
Praesent facilisis faucibus neque, ut ullamcorper lacus gravida a. Donec vel iaculis sapien."  width="90%" editable="false" visible="{data!=null?true:false}"/> 
</s:View>

The resulting application:

You could also set a layout on the SplitViewNavigator container so if you wanted it to split vertically for instance, you would simply set a VerticalLayout, and adjust the height percentages with the width set to 100%, such as:

<s:SplitViewNavigator id="svn" width="100%" height="100%">
	<s:layout>
	     <s:VerticalLayout/>
	</s:layout>
	<s:ViewNavigator id="leftNav" width="100%" height="30%" firstView="views.LeftView"/>
	<s:ViewNavigator id="rightNav" width="100%" height="70%" firstView="views.RightView"/>
</s:SplitViewNavigator>

Here’s the updated layout:

This split view approach works well for landscape mode, however, in portrait mode you may want to display it a little differently since the screen width is much less to work with. There are some built-in features to help you do this. There’s an autoHideFirstViewNavigator property on the SplitViewNavigator that will automatically hide the left side view when the application receives an orientation change event to portrait.

<s:SplitViewNavigator id="svn" width="100%" height="100%" autoHideFirstViewNavigator="true">
	<s:ViewNavigator id="leftNav" width="30%" height="100%" firstView="views.LeftView"/>
	<s:ViewNavigator id="rightNav" width="100%" height="100%" firstView="views.RightView"/>
</s:SplitViewNavigator>

Now when we run it, we will see the following:

Not very useful yet though since there’s no way to navigate to a different item in our list! So we need to take this one step further and use the showViewNavigatorInPopUp function from the SplitViewNavigator to pop up our list in a Callout while in portrait mode. We can call this function from a button in the right ViewNavigator’s actionBar navigationContent for instance such as the following:

<s:SplitViewNavigator id="svn" width="100%" height="100%" autoHideFirstViewNavigator="true">
		<s:ViewNavigator id="leftNav" width="30%" height="100%" firstView="views.LeftView"/>
		<s:ViewNavigator id="rightNav" width="100%" height="100%" firstView="views.RightView" >
			<s:navigationContent>
				<s:Button id="listButton" label="List" click="svn.showFirstViewNavigatorInPopUp(listButton)"/>
			</s:navigationContent>
		</s:ViewNavigator>
</s:SplitViewNavigator>

Note: Just to clarify, in the above we are using the actionBar already implicitly defined as part of the Spark ViewNavigator container and setting the parent for the popup to the listButton, so the Callout or popup arrow will stem from that button. Here’s what the above code will look like when run in portrait mode:

At this point, we probably don’t want this button to show though when going back into landscape mode, so we’ll need to add states management to set visible to false when in landscape. One way to determine when to update the state would be to add a resize event handler and check the width and height and update the state accordingly. Our code now looks like the following:

<?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="application1_resizeHandler(event)">
	<fx:Script>
		<![CDATA[
			import mx.events.ResizeEvent;
			
			protected function application1_resizeHandler(event:ResizeEvent):void
			{
				if (width>height)
					this.currentState="landscape";
				else this.currentState="portrait";
			}
		]]>
	</fx:Script>
	
	<s:states>
		<s:State name="portrait"/>
		<s:State name="landscape"/>
	</s:states>
	
	<s:SplitViewNavigator id="svn" width="100%" height="100%" autoHideFirstViewNavigator="true">
		<s:ViewNavigator id="leftNav" width="30%" height="100%" firstView="views.LeftView"/>
		<s:ViewNavigator id="rightNav" width="100%" height="100%" firstView="views.RightView" >
			<s:navigationContent>
				<s:Button id="listButton" label="List" click="svn.showFirstViewNavigatorInPopUp(listButton)" visible.landscape="false"/>
			</s:navigationContent>
		</s:ViewNavigator>
	</s:SplitViewNavigator>		
</s:Application>

Now when we run the application in landscape mode, we can see the List button is not showing in the actionBar:

You can download the source and project file for this sample application here!

Also, if you haven’t looked at this yet, Christophe and I created an extensive SplitViewNavigator-based expense tracking tablet application called XpenseIt that includes a bunch of other Flex 4.6 features as well and can be downloaded here. Here is a screenshot from that application:

Filed in: Flash Builder 4.6FlexFlex 4.5Flex 4.5/MobileFlex 4.6Flex Mobile Tags:

About the Author ()

Comments (37)

Trackback URL | Comments RSS Feed

  1. FlexLover says:

    Nice one. Thanks Holly.

  2. Hi Holly,

    Maybe you could help me out here as I’ve search the web and Adobe forum but could not find any answer.

    I just installed Flash Builder 4.6 (after uninstalling 4.5.1), now when I run my app, the adl.exe crashes (error details below). I thought because I have an app that was created with 4.5, but then I created a new app with this version and it still crash. I have Windows 7 64-bit PC.

    Thanks so much. Any help is greatly appreciated.

    Error details:

    Problem signature:
    Problem Event Name: APPCRASH
    Application Name: adl.exe
    Application Version: 3.1.0.4880
    Application Timestamp: 4eb7612e
    Fault Module Name: Adobe AIR.dll
    Fault Module Version: 3.1.0.4880
    Fault Module Timestamp: 4eb75fb9
    Exception Code: c0000005
    Exception Offset: 000a8a5b
    OS Version: 6.1.7600.2.0.0.256.48
    Locale ID: 1033
    Additional Information 1: 0a9e
    Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
    Additional Information 3: 0a9e
    Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

    Read our privacy statement online:
    http://go.microsoft.com/fwlink/?linkid=104288&clcid=0×0409

    If the online privacy statement is not available, please read our privacy statement offline:
    C:\Windows\system32\en-US\erofflps.txt

    And more error message below:

    Process terminated unexpectedly.

    Launch command details: “C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0 (AIR 3.1)\bin\adl.exe” -runtime “C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0 (AIR 3.1)\runtimes\air\win” -profile mobileDevice -screensize 320×460:320×480 -XscreenDPI 163 -XversionPlatform IOS “C:\Users\joel.badinas.ENTICENT\Adobe Flash Builder 4.6\MobileLab\bin-debug\MobileLab-app.xml” “C:\Users\joel.badinas.ENTICENT\Adobe Flash Builder 4.6\MobileLab\bin-debug”

  3. Kevin says:

    Nice post Holly! Timely information.

    Question for pointer in the right direction:

    I’d like to allow preferences to be set for my iPad application via the ‘Settings’ application. In a native IOS application, this is configured in a Root.plist file as detailed in the link below.

    http://iphoneincubator.com/blog/tutorial/how-to-create-an-iphone-preferences-file

    Does Flash Builder have any capabilities in this direction that you’re aware of? You earlier blog post on was a great help, but I’m at a dead-end trying to locating any further information in this realm.

  4. Mark says:

    Hi Holly,
    Is it possible to compile mobile projects in FlashBuilder to an .swf to run in a PC’s browser/flash run-time? I’d like to use the same or near the same code-base for both the tablet, and PC based browser if possible.

  5. Konstantin says:

    Hi Holly!
    Is it possible to create a mobile (iOS) app with flash builder which has lets say a TabbedView_Layout on iPhone and a SplitView on Tablet. So, is there a way to detect the device/resolution on startup and create different, according views?
    Or would you suggest to build two/multiple different apps to achive this?
    Looking forward to a response and to new Tutorials! :)
    Thank you!

    • Hi Holly,

      I am also wondering whether I need to build separate apps for IPad and Iphone? As per @Konstantin’s question above..

      Any pointers on this one would be most appreciated :)

      Thanks for all your content..

  6. Todd Hamilton says:

    I am also seeing adl.exe crashing (as mentioned in other’s comments. Was there a solution found? There are quite a few complaints about this out there and no answers (that I have found).. Thanks.

  7. Rehan says:

    Hi,
    How can I change the color of the separator line between the left and the right view navigators ?

    Thanks

  8. Mateusz Maćkowiak says:

    Hi,
    Got a question about the “showFirstViewNavigatorInPopUp”. I came across a problem when pressing a button that dispaches that function. Simple thing.A button exists only on landscape like in Your example. but when I press the button meny times fast it does strange things. Checking if the popupIsOpen does not help. I see that this is not only my problem after checking the newes app by Michaël Chaize. Any help?
    Can send some pics.

  9. Pulkit Gupta says:

    Callout thing is very buggy. First it doesn’t take into consideration the scaleFactor of the application when scaled to suit a particular screen resolution. Besides this, there are other issues in the arrow component.

  10. Why flex application are so slow?

  11. Mano says:

    Hi,
    i have a problem, i was using Flex 4.5.1. Need to develop an Alarm application for iphone and android. I was researching with google and Adobe site and found we have to use Local Notification class to do an Alarm App. But Flex 4.5.1 is not supporting native functions and herd adobe has launched 4.6 which support native function and i converted to 4.6. Now the same problem here also, there is no default classes and get an example script from Adobe Blog itself which has the native Local Notification Class. But there they used just very simple method and used button click to dispatch the notification event. I searched with Apple SDK there they used an method and class called Scheduler to schedule an event and triggers then by automatic at particular time. But with flex i don’t see that method. Could you please advice me can we do this with Flex and how? if possible with an example.

  12. David says:

    Hi

    Can the new component “SplitViewNavigator”, “ViewNavigator” , “CalloutButton”, “DateSpinner”
    be used in the basic Flex Project instead of “Mobile Flex Project. Because, whenever I use those in the Flex Project (Builder 46)
    I got an error; It seems that those components do not exist in the Sparl namespace.

    Then, can I use theese component in a standard FLex Project to build a Web App.

    Thank you for your anwser

    Regards
    David

  13. kyle says:

    Have you had any luck getting the chrome color to change on the actionbar’s of the views? I’ve tried everything I could think of to get the background color of the actionbar to change and nothing seems to work.

  14. richard campbell says:

    I have created an app using the splitviewnavigator but I am trying to allow for navigating the app using swipes on the detail view that will then push the next item from the list view.

    How can I do this?

  15. CincyPlanet says:

    Great Article. I am working a new app and this came in handy for a cool feature.

  16. Simadri says:

    Hi Holly,
    I am developing a app for my testing purpose in flash builder 4.5 and flex SDK 4.5.1 . So is there any component available in flex SDK 4.5 to achieve same functionality as ?

    plz help me, am stuck at this point.

    Thanks,
    Simadri

    • Hi Samadri, there is a way to do this in 4.5.1, I actually have an example project that mimics the SplitViewNavigator approach here that you can download and look at (it’s an fxp so import into Flash Builder). Hope that helps! Holly

  17. francesco says:

    Hi Holly,
    Hi Holly,
    congratulation for the blog, it’s very helpfull.
    I have a question about SplitViewNavigator (really about a button in general):
    when I click a Button (menu or back for example) in my mobile device, I have a typical “Click” sound. How can I add this sound on my button? I want add the typical device sound of my device in my app.
    Is it possible?
    Thanks!!!
    Francesco

  18. Thank you very much holly, your articles are always nice and this one helped me great!

  19. Antonio says:

    Hi Holly, great article. I’m trying to use on my app but i have a problem. Is it possible to do something like ‘this.rightNav.popView()’? I’ve read i have to take care of the Back Button when using the splitview. I don’t know if i can do what i need. I have a splitview, on the left view i have a list, on the right i load a view with a list, when i click on the right list y push a details view. What i need is to back to the right list when the user uses the Back Button. Is this possible? I have tried using this handlers:

    systemManager.stage.addEventListener(KeyboardEvent.KEY_DOWN, deviceKeyDownHandler);
    systemManager.stage.addEventListener(KeyboardEvent.KEY_UP, deviceKeyUpHandler);

    but nothing happens. Any hint? Thanks

  20. Prem says:

    Great Article!!

    I am trying to use the SplitViewNavigator without the autoHideFirstNavigator. I want to do it programmatically so I can have user interaction to hide it and display the button for the callout or on orientation change.
    So that works great, I do
    var svn:SplitViewNavigator = FlexGlobals.topLevelApplication.mainSvn as SplitViewNavigator;
    svn.getViewNavigatorAt(0).visible = false;

    and I can call showFirstViewNavigatorInPopup() to display the popup

    The problem is if I want to restore it

    If I do

    var svn:SplitViewNavigator = FlexGlobals.topLevelApplication.mainSvn as SplitViewNavigator;
    svn.hideViewNavigatorPopUp();
    svn.getViewNavigatorAt(0).visible = true;

    Nothing happens , the first pane is not restored !!! Any ideas as to what I am doing wrong ? According to the documentation it says “After closing the popup, the navigator that was shown remains invisible unless autoHideFirstViewNavigator is true and the device orientation is landscape. In all other cases, the visibility of the first navigator needs to be set to true to make it visible again.”

    Thanks much

  21. Owen Corso says:

    any suggestions on how to do some environment detection to show Master/Detail on iPad vs just Master for smaller iPhone screens/or portrait. (like the way mail works in portait on iPady)?

  22. RaMel says:

    Is there a way to go from split view navigation to a standard view? I want to use split view for the app admin. When they hit the back button

  23. Joe says:

    Someone mentioned in the comments something similar to pushing a view onto the RightView of the Split Navigator (once a list in the left view is tapped.

    There are time where more than just data is being passed to the right view, but actually need a whole different view to be changed.

    Any ideas on pushing a view just on the right view of the SplitViewNavigator?

    Thanks

  24. Vishnuprasad says:

    Hi Holly

    Gr8 work . i am newbi starting flex based mobile application it would be gr8 if you have a source code for this demo

  25. Pooja Gupta says:

    Hi Holly,

    Great article.
    I have used splitviewnavigator in an app. The issue I am facing is that when the app goes to potrait mode, the first view does hides and I have added a button too to show the first view in a popup…but my popup does not appear like yours. The first view’ title comes on top of the button name.

    Please help.

    Regards,
    Pooja

  26. Alain Levy says:

    Hi Holly,

    Great stuff, but I am pulling my hair out!

    I am getting an error on

    (this.parentDocument as Sample).rightNav…

    It does not like rightNav (119: Access of possibly undefined property rightNav through a reference with static type flash.sampler:Sample.)

    The only difference I have with your sample app is that the SplitViewNavigator is not in a <s:Application container but in a <s:SkinnablePopUpContainer page.

    I guess that's where the problem lies.

    Any suggestion? Thanks,

    Alain

Leave a Reply